]> git.pld-linux.org Git - packages/lighttpd.git/blob - lighttpd-branch.diff
- created
[packages/lighttpd.git] / lighttpd-branch.diff
1
2 Property changes on: debian/menu.ex
3 ___________________________________________________________________
4 Name: svn:eol-style
5    + native
6
7
8 Property changes on: debian/control
9 ___________________________________________________________________
10 Name: svn:eol-style
11    + native
12
13
14 Property changes on: debian/emacsen-remove.ex
15 ___________________________________________________________________
16 Name: svn:eol-style
17    + native
18
19
20 Property changes on: debian/watch.ex
21 ___________________________________________________________________
22 Name: svn:eol-style
23    + native
24
25
26 Property changes on: debian/manpage.1.ex
27 ___________________________________________________________________
28 Name: svn:eol-style
29    + native
30
31
32 Property changes on: debian/manpage.xml.ex
33 ___________________________________________________________________
34 Name: svn:eol-style
35    + native
36
37
38 Property changes on: debian/compat
39 ___________________________________________________________________
40 Name: svn:eol-style
41    + native
42
43
44 Property changes on: debian/manpage.sgml.ex
45 ___________________________________________________________________
46 Name: svn:eol-style
47    + native
48
49
50 Property changes on: debian/init.d
51 ___________________________________________________________________
52 Name: svn:eol-style
53    + native
54
55
56 Property changes on: debian/emacsen-startup.ex
57 ___________________________________________________________________
58 Name: svn:eol-style
59    + native
60
61
62 Property changes on: debian/changelog
63 ___________________________________________________________________
64 Name: svn:eol-style
65    + native
66
67
68 Property changes on: debian/docs
69 ___________________________________________________________________
70 Name: svn:eol-style
71    + native
72
73
74 Property changes on: debian/README.Debian.ex
75 ___________________________________________________________________
76 Name: svn:eol-style
77    + native
78
79
80 Property changes on: debian/emacsen-install.ex
81 ___________________________________________________________________
82 Name: svn:eol-style
83    + native
84
85
86 Property changes on: debian/rules
87 ___________________________________________________________________
88 Name: svn:eol-style
89    + native
90
91
92 Property changes on: debian/cron.d.ex
93 ___________________________________________________________________
94 Name: svn:eol-style
95    + native
96
97
98 Property changes on: debian/postrm.ex
99 ___________________________________________________________________
100 Name: svn:eol-style
101    + native
102
103
104 Property changes on: debian/preinst.ex
105 ___________________________________________________________________
106 Name: svn:eol-style
107    + native
108
109
110 Property changes on: debian/prerm.ex
111 ___________________________________________________________________
112 Name: svn:eol-style
113    + native
114
115
116 Property changes on: debian/dirs
117 ___________________________________________________________________
118 Name: svn:eol-style
119    + native
120
121
122 Property changes on: debian/lighttpd.postinst
123 ___________________________________________________________________
124 Name: svn:eol-style
125    + native
126
127
128 Property changes on: debian/lighttpd.conf
129 ___________________________________________________________________
130 Name: svn:eol-style
131    + native
132
133
134 Property changes on: debian/lighttpd.doc-base.EX
135 ___________________________________________________________________
136 Name: svn:eol-style
137    + native
138
139
140 Property changes on: debian/copyright
141 ___________________________________________________________________
142 Name: svn:eol-style
143    + native
144
145
146 Property changes on: debian/conffiles
147 ___________________________________________________________________
148 Name: svn:eol-style
149    + native
150
151
152 Property changes on: debian/Makefile.am
153 ___________________________________________________________________
154 Name: svn:eol-style
155    + native
156
157
158 Property changes on: debian/lighttpd-default.ex
159 ___________________________________________________________________
160 Name: svn:eol-style
161    + native
162
163
164 Property changes on: debian/.cvsignore
165 ___________________________________________________________________
166 Name: svn:eol-style
167    + native
168
169
170 Property changes on: debian/lighttpd.logrotate
171 ___________________________________________________________________
172 Name: svn:eol-style
173    + native
174
175
176 Property changes on: AUTHORS
177 ___________________________________________________________________
178 Name: svn:eol-style
179    + native
180
181 Index: configure.in
182 ===================================================================
183 --- configure.in        (.../tags/lighttpd-1.4.11)      (revision 1159)
184 +++ configure.in        (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
185 @@ -1,7 +1,7 @@
186  #                                               -*- Autoconf -*-
187  # Process this file with autoconf to produce a configure script.
188  AC_PREREQ(2.57)
189 -AC_INIT(lighttpd, 1.4.11, jan@kneschke.de)
190 +AC_INIT(lighttpd, 1.4.12, jan@kneschke.de)
191  AC_CONFIG_SRCDIR([src/server.c])
192  
193  AC_CANONICAL_TARGET
194 @@ -66,7 +66,7 @@
195  AC_TYPE_PID_T
196  AC_TYPE_SIZE_T
197  
198 -AC_CHECK_MEMBER(struct tm.tm_gmtoff,AC_DEFINE([HAVE_STRUCT_TM_GMTOFF],[1],[gmtoff in struct tm]),,[#include <time.h>])
199 +AC_CHECK_MEMBER(struct tm.tm_gmtoff,[AC_DEFINE([HAVE_STRUCT_TM_GMTOFF],[1],[gmtoff in struct tm])],,[#include <time.h>])
200  AC_CHECK_TYPES(struct sockaddr_storage,,,[#include <sys/socket.h>])
201  AC_CHECK_TYPES(socklen_t,,,[#include <sys/types.h>
202  #include <sys/socket.h>])
203 @@ -339,6 +339,22 @@
204      AC_DEFINE([HAVE_SQLITE3], [1], [libsqlite3])
205      AC_DEFINE([HAVE_SQLITE3_H], [1], [sqlite3.h])
206   ])
207 +
208 + AC_MSG_CHECKING(for locks in mod_webdav)
209 + AC_ARG_WITH(webdav-locks, AC_HELP_STRING([--with-webdav-locks],[locks in mod_webdav]),
210 + [WITH_WEBDAV_LOCKS=$withval],[WITH_WEBDAV_LOCKS=no])
211 + AC_MSG_RESULT([$WITH_WEBDAV_LOCKS])
212 +
213 + if test "$WITH_WEBDAV_LOCKS" != "no"; then
214 +   AC_CHECK_LIB(uuid, uuid_unparse, [
215 +         AC_CHECK_HEADERS([uuid/uuid.h],[
216 +                 UUID_LIB=-luuid
217 +                 AC_DEFINE([HAVE_UUID], [1], [libuuid])
218 +                AC_DEFINE([HAVE_UUID_H], [1], [uuid/uuid.h is available])
219 +         ])
220 + ])
221 +
222 + fi
223  fi
224  
225  dnl Check for gdbm
226 @@ -381,31 +397,12 @@
227  
228  AC_MSG_RESULT($WITH_LUA)
229  if test "$WITH_LUA" != "no"; then
230 - AC_PATH_PROG(LUACONFIG, lua-config)
231 -
232 - if test x"$LUACONFIG" != x; then
233 -   LUA_CFLAGS=`$LUACONFIG --include`
234 -   LUA_LIBS=`$LUACONFIG --libs --extralibs`
235 + # try pkgconfig
236 + PKG_CHECK_MODULES(LUA, lua >= 5.1, [
237     AC_DEFINE([HAVE_LUA], [1], [liblua])
238     AC_DEFINE([HAVE_LUA_H], [1], [lua.h])
239 - else
240 -   AC_CHECK_LIB(lua, lua_open, [
241 -     AC_CHECK_HEADERS([lua.h],[
242 -       LUA_LIBS="-llua -llualib"
243 -       AC_DEFINE([HAVE_LUA], [1], [liblua])
244 -       AC_DEFINE([HAVE_LUA_H], [1], [lua.h])
245 -     ])
246 -   ])
247 - fi
248 + ])
249  
250 - if test x"$LUA_LIBS" = x; then
251 -   # try pkgconfig
252 -   PKG_CHECK_MODULES(LUA, lua, [
253 -     AC_DEFINE([HAVE_LUA], [1], [liblua])
254 -     AC_DEFINE([HAVE_LUA_H], [1], [lua.h])
255 -   ])
256 - fi
257 -
258   AC_SUBST(LUA_CFLAGS)
259   AC_SUBST(LUA_LIBS)
260  fi
261 @@ -440,7 +437,7 @@
262  esac
263  
264  AC_CHECK_FUNCS([dup2 getcwd inet_ntoa inet_ntop memset mmap munmap strchr \
265 -                 strdup strerror strstr strtol sendfile  getopt socket \
266 +                 strdup strerror strstr strtol sendfile  getopt socket lstat \
267                   gethostbyname poll sigtimedwait epoll_ctl getrlimit chroot \
268                   getuid select signal pathconf madvise posix_fadvise posix_madvise \
269                   writev sigaction sendfile64 send_file kqueue port_create localtime_r])
270 @@ -538,7 +535,7 @@
271  AC_OUTPUT
272  
273  
274 -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" 
275 +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" 
276  
277  plugins="mod_rewrite mod_redirect mod_ssi mod_trigger_b4_dl"
278  features="regex-conditionals"
279 @@ -642,6 +639,14 @@
280         disable_feature="$disable_feature $features"
281  fi
282  
283 +features="webdav-locks"
284 +if test "x$UUID_LIB" \!= x; then
285 +       enable_feature="$enable_feature $features"
286 +else
287 +       disable_feature="$disable_feature $features"
288 +fi
289 +
290 +
291  ## output
292  
293  $ECHO
294
295 Property changes on: configure.in
296 ___________________________________________________________________
297 Name: svn:eol-style
298    + native
299
300
301 Property changes on: ChangeLog
302 ___________________________________________________________________
303 Name: svn:eol-style
304    + native
305
306 Index: src/data_config.c
307 ===================================================================
308 --- src/data_config.c   (.../tags/lighttpd-1.4.11)      (revision 1159)
309 +++ src/data_config.c   (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
310 @@ -17,26 +17,26 @@
311  
312  static void data_config_free(data_unset *d) {
313         data_config *ds = (data_config *)d;
314 -       
315 +
316         buffer_free(ds->key);
317         buffer_free(ds->op);
318         buffer_free(ds->comp_key);
319 -       
320 +
321         array_free(ds->value);
322         array_free(ds->childs);
323 -       
324 +
325         if (ds->string) buffer_free(ds->string);
326  #ifdef HAVE_PCRE_H
327         if (ds->regex) pcre_free(ds->regex);
328         if (ds->regex_study) pcre_free(ds->regex_study);
329  #endif
330 -       
331 +
332         free(d);
333  }
334  
335  static void data_config_reset(data_unset *d) {
336         data_config *ds = (data_config *)d;
337 -       
338 +
339         /* reused array elements */
340         buffer_reset(ds->key);
341         buffer_reset(ds->comp_key);
342 @@ -45,9 +45,9 @@
343  
344  static int data_config_insert_dup(data_unset *dst, data_unset *src) {
345         UNUSED(dst);
346 -       
347 +
348         src->free(src);
349 -       
350 +
351         return 0;
352  }
353  
354 @@ -56,7 +56,7 @@
355         array *a = (array *)ds->value;
356         size_t i;
357         size_t maxlen;
358 -       
359 +
360         if (0 == ds->context_ndx) {
361                 fprintf(stderr, "config {\n");
362         }
363 @@ -117,22 +117,22 @@
364  
365  data_config *data_config_init(void) {
366         data_config *ds;
367 -       
368 +
369         ds = calloc(1, sizeof(*ds));
370 -       
371 +
372         ds->key = buffer_init();
373         ds->op = buffer_init();
374         ds->comp_key = buffer_init();
375         ds->value = array_init();
376         ds->childs = array_init();
377         ds->childs->is_weakref = 1;
378 -       
379 +
380         ds->copy = data_config_copy;
381         ds->free = data_config_free;
382         ds->reset = data_config_reset;
383         ds->insert_dup = data_config_insert_dup;
384         ds->print = data_config_print;
385         ds->type = TYPE_CONFIG;
386 -       
387 +
388         return ds;
389  }
390
391 Property changes on: src/data_config.c
392 ___________________________________________________________________
393 Name: svn:eol-style
394    + native
395
396 Index: src/configfile-glue.c
397 ===================================================================
398 --- src/configfile-glue.c       (.../tags/lighttpd-1.4.11)      (revision 1159)
399 +++ src/configfile-glue.c       (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
400 @@ -1,4 +1,5 @@
401  #include <string.h>
402 +#include <ctype.h>
403  
404  #include "base.h"
405  #include "buffer.h"
406 @@ -11,10 +12,10 @@
407   * are the external interface of lighttpd. The functions
408   * are used by the server itself and the plugins.
409   *
410 - * The main-goal is to have a small library in the end 
411 - * which is linked against both and which will define 
412 + * The main-goal is to have a small library in the end
413 + * which is linked against both and which will define
414   * the interface itself in the end.
415 - * 
416 + *
417   */
418  
419  
420 @@ -24,56 +25,60 @@
421  int config_insert_values_internal(server *srv, array *ca, const config_values_t cv[]) {
422         size_t i;
423         data_unset *du;
424 -       
425 +
426         for (i = 0; cv[i].key; i++) {
427 -               
428 +
429                 if (NULL == (du = array_get_element(ca, cv[i].key))) {
430                         /* no found */
431 -                       
432 +
433                         continue;
434                 }
435 -               
436 +
437                 switch (cv[i].type) {
438                 case T_CONFIG_ARRAY:
439                         if (du->type == TYPE_ARRAY) {
440                                 size_t j;
441                                 data_array *da = (data_array *)du;
442 -                               
443 +
444                                 for (j = 0; j < da->value->used; j++) {
445                                         if (da->value->data[j]->type == TYPE_STRING) {
446                                                 data_string *ds = data_string_init();
447 -                                               
448 +
449                                                 buffer_copy_string_buffer(ds->value, ((data_string *)(da->value->data[j]))->value);
450                                                 if (!da->is_index_key) {
451                                                         /* the id's were generated automaticly, as we copy now we might have to renumber them
452 -                                                        * this is used to prepend server.modules by mod_indexfiles as it has to be loaded 
453 +                                                        * this is used to prepend server.modules by mod_indexfiles as it has to be loaded
454                                                          * before mod_fastcgi and friends */
455                                                         buffer_copy_string_buffer(ds->key, ((data_string *)(da->value->data[j]))->key);
456                                                 }
457 -                                               
458 +
459                                                 array_insert_unique(cv[i].destination, (data_unset *)ds);
460                                         } else {
461 -                                               log_error_write(srv, __FILE__, __LINE__, "sssd", 
462 -                                                               "the key of and array can only be a string or a integer, variable:", 
463 -                                                               cv[i].key, "type:", da->value->data[j]->type); 
464 -                                               
465 +                                               log_error_write(srv, __FILE__, __LINE__, "sssd",
466 +                                                               "the key of and array can only be a string or a integer, variable:",
467 +                                                               cv[i].key, "type:", da->value->data[j]->type);
468 +
469                                                 return -1;
470                                         }
471                                 }
472                         } else {
473                                 log_error_write(srv, __FILE__, __LINE__, "sss", "unexpected type for key: ", cv[i].key, "array of strings");
474 -                               
475 +
476                                 return -1;
477                         }
478                         break;
479                 case T_CONFIG_STRING:
480                         if (du->type == TYPE_STRING) {
481                                 data_string *ds = (data_string *)du;
482 -                               
483 +
484                                 buffer_copy_string_buffer(cv[i].destination, ds->value);
485 +                       } else if (du->type == TYPE_INTEGER) {
486 +                               data_integer *di = (data_integer *)du;
487 +
488 +                               buffer_copy_long(cv[i].destination, di->value);
489                         } else {
490                                 log_error_write(srv, __FILE__, __LINE__, "ssss", "unexpected type for key: ", cv[i].key, "(string)", "\"...\"");
491 -                               
492 +
493                                 return -1;
494                         }
495                         break;
496 @@ -81,15 +86,20 @@
497                         switch(du->type) {
498                         case TYPE_INTEGER: {
499                                 data_integer *di = (data_integer *)du;
500 -                               
501 +
502                                 *((unsigned short *)(cv[i].destination)) = di->value;
503                                 break;
504                         }
505                         case TYPE_STRING: {
506                                 data_string *ds = (data_string *)du;
507 -                                       
508 +
509 +                               if (buffer_isdigit(ds->value)) {
510 +                                       *((unsigned short *)(cv[i].destination)) = strtol(ds->value->ptr, NULL, 10);
511 +                                       break;
512 +                               }
513 +
514                                 log_error_write(srv, __FILE__, __LINE__, "ssb", "get a string but expected a short:", cv[i].key, ds->value);
515 -                               
516 +
517                                 return -1;
518                         }
519                         default:
520 @@ -100,19 +110,19 @@
521                 case T_CONFIG_BOOLEAN:
522                         if (du->type == TYPE_STRING) {
523                                 data_string *ds = (data_string *)du;
524 -                               
525 +
526                                 if (buffer_is_equal_string(ds->value, CONST_STR_LEN("enable"))) {
527                                         *((unsigned short *)(cv[i].destination)) = 1;
528                                 } else if (buffer_is_equal_string(ds->value, CONST_STR_LEN("disable"))) {
529                                         *((unsigned short *)(cv[i].destination)) = 0;
530                                 } else {
531                                         log_error_write(srv, __FILE__, __LINE__, "ssbs", "ERROR: unexpected value for key:", cv[i].key, ds->value, "(enable|disable)");
532 -                                               
533 +
534                                         return -1;
535                                 }
536                         } else {
537                                 log_error_write(srv, __FILE__, __LINE__, "ssss", "ERROR: unexpected type for key:", cv[i].key, "(string)", "\"(enable|disable)\"");
538 -                               
539 +
540                                 return -1;
541                         }
542                         break;
543 @@ -121,9 +131,9 @@
544                         break;
545                 case T_CONFIG_DEPRECATED:
546                         log_error_write(srv, __FILE__, __LINE__, "ssss", "ERROR: found deprecated key:", cv[i].key, "-", (char *)(cv[i].destination));
547 -                       
548 +
549                         srv->config_deprecated = 1;
550 -                       
551 +
552                         break;
553                 }
554         }
555 @@ -133,25 +143,25 @@
556  int config_insert_values_global(server *srv, array *ca, const config_values_t cv[]) {
557         size_t i;
558         data_unset *du;
559 -       
560 +
561         for (i = 0; cv[i].key; i++) {
562                 data_string *touched;
563 -               
564 +
565                 if (NULL == (du = array_get_element(ca, cv[i].key))) {
566                         /* no found */
567 -                       
568 +
569                         continue;
570                 }
571 -               
572 +
573                 /* touched */
574                 touched = data_string_init();
575 -               
576 +
577                 buffer_copy_string(touched->value, "");
578                 buffer_copy_string_buffer(touched->key, du->key);
579 -               
580 +
581                 array_insert_unique(srv->config_touched, (data_unset *)touched);
582         }
583 -       
584 +
585         return config_insert_values_internal(srv, ca, cv);
586  }
587  
588 @@ -191,25 +201,25 @@
589         }
590  
591         /* pass the rules */
592 -       
593 +
594         switch (dc->comp) {
595         case COMP_HTTP_HOST: {
596                 char *ck_colon = NULL, *val_colon = NULL;
597 -               
598 +
599                 if (!buffer_is_empty(con->uri.authority)) {
600 -               
601 -                       /* 
602 +
603 +                       /*
604                          * append server-port to the HTTP_POST if necessary
605                          */
606 -                       
607 +
608                         l = con->uri.authority;
609 -                       
610 +
611                         switch(dc->cond) {
612                         case CONFIG_COND_NE:
613                         case CONFIG_COND_EQ:
614                                 ck_colon = strchr(dc->string->ptr, ':');
615                                 val_colon = strchr(l->ptr, ':');
616 -                               
617 +
618                                 if (ck_colon == val_colon) {
619                                         /* nothing to do with it */
620                                         break;
621 @@ -230,21 +240,21 @@
622                                 break;
623                         }
624                 } else {
625 -                       l = NULL;
626 +                       l = srv->empty_string;
627                 }
628                 break;
629         }
630         case COMP_HTTP_REMOTEIP: {
631                 char *nm_slash;
632 -               /* handle remoteip limitations 
633 -                * 
634 +               /* handle remoteip limitations
635 +                *
636                  * "10.0.0.1" is provided for all comparisions
637 -                * 
638 +                *
639                  * only for == and != we support
640 -                * 
641 +                *
642                  * "10.0.0.1/24"
643                  */
644 -               
645 +
646                 if ((dc->cond == CONFIG_COND_EQ ||
647                      dc->cond == CONFIG_COND_NE) &&
648                     (con->dst_addr.plain.sa_family == AF_INET) &&
649 @@ -253,41 +263,48 @@
650                         long nm;
651                         char *err;
652                         struct in_addr val_inp;
653 -                       
654 +
655 +                       if (con->conf.log_condition_handling) {
656 +                               l = srv->empty_string;
657 +
658 +                               log_error_write(srv, __FILE__, __LINE__,  "bsbsb", dc->comp_key,
659 +                                               "(", l, ") compare to", dc->string);
660 +                       }
661 +
662                         if (*(nm_slash+1) == '\0') {
663                                 log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: no number after / ", dc->string);
664 -                                       
665 +
666                                 return COND_RESULT_FALSE;
667                         }
668 -                       
669 +
670                         nm_bits = strtol(nm_slash + 1, &err, 10);
671 -                       
672 +
673                         if (*err) {
674                                 log_error_write(srv, __FILE__, __LINE__, "sbs", "ERROR: non-digit found in netmask:", dc->string, *err);
675 -                               
676 +
677                                 return COND_RESULT_FALSE;
678                         }
679 -                       
680 +
681                         /* take IP convert to the native */
682                         buffer_copy_string_len(srv->cond_check_buf, dc->string->ptr, nm_slash - dc->string->ptr);
683 -#ifdef __WIN32                 
684 +#ifdef _WIN32
685                         if (INADDR_NONE == (val_inp.s_addr = inet_addr(srv->cond_check_buf->ptr))) {
686                                 log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: ip addr is invalid:", srv->cond_check_buf);
687 -                               
688 +
689                                 return COND_RESULT_FALSE;
690                         }
691  
692  #else
693                         if (0 == inet_aton(srv->cond_check_buf->ptr, &val_inp)) {
694                                 log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: ip addr is invalid:", srv->cond_check_buf);
695 -                               
696 +
697                                 return COND_RESULT_FALSE;
698                         }
699  #endif
700 -                       
701 +
702                         /* build netmask */
703                         nm = htonl(~((1 << (32 - nm_bits)) - 1));
704 -                       
705 +
706                         if ((val_inp.s_addr & nm) == (con->dst_addr.ipv4.sin_addr.s_addr & nm)) {
707                                 return (dc->cond == CONFIG_COND_EQ) ? COND_RESULT_TRUE : COND_RESULT_FALSE;
708                         } else {
709 @@ -308,7 +325,7 @@
710  
711         case COMP_HTTP_REFERER: {
712                 data_string *ds;
713 -               
714 +
715                 if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Referer"))) {
716                         l = ds->value;
717                 } else {
718 @@ -338,7 +355,7 @@
719         default:
720                 return COND_RESULT_FALSE;
721         }
722 -       
723 +
724         if (NULL == l) {
725                 if (con->conf.log_condition_handling) {
726                         log_error_write(srv, __FILE__, __LINE__,  "bsbs", dc->comp_key,
727 @@ -346,10 +363,10 @@
728                 }
729                 return COND_RESULT_FALSE;
730         }
731 -       
732 +
733         if (con->conf.log_condition_handling) {
734                 log_error_write(srv, __FILE__, __LINE__,  "bsbsb", dc->comp_key,
735 -                               "(", l, ") compare to ", dc->string);
736 +                               "(", l, ") compare to", dc->string);
737         }
738         switch(dc->cond) {
739         case CONFIG_COND_NE:
740 @@ -365,13 +382,13 @@
741         case CONFIG_COND_MATCH: {
742                 cond_cache_t *cache = &con->cond_cache[dc->context_ndx];
743                 int n;
744 -               
745 +
746  #ifndef elementsof
747  #define elementsof(x) (sizeof(x) / sizeof(x[0]))
748  #endif
749                 n = pcre_exec(dc->regex, dc->regex_study, l->ptr, l->used - 1, 0, 0,
750                                 cache->matches, elementsof(cache->matches));
751 -               
752 +
753                 cache->patterncount = n;
754                 if (n > 0) {
755                         cache->comp_value = l;
756 @@ -387,7 +404,7 @@
757                 /* no way */
758                 break;
759         }
760 -       
761 +
762         return COND_RESULT_FALSE;
763  }
764  
765 @@ -395,6 +412,9 @@
766         cond_cache_t *caches = con->cond_cache;
767  
768         if (COND_RESULT_UNSET == caches[dc->context_ndx].result) {
769 +               if (con->conf.log_condition_handling) {
770 +                       log_error_write(srv, __FILE__, __LINE__,  "sds",  "=== start of", dc->context_ndx, "condition block ===");
771 +               }
772                 if (COND_RESULT_TRUE == (caches[dc->context_ndx].result = config_check_cond_nocache(srv, con, dc))) {
773                         if (dc->next) {
774                                 data_config *c;
775 @@ -409,11 +429,11 @@
776                 }
777                 if (con->conf.log_condition_handling) {
778                         log_error_write(srv, __FILE__, __LINE__, "dss", dc->context_ndx,
779 -                                       "(uncached) result:",
780 +                                       "result:",
781                                         caches[dc->context_ndx].result == COND_RESULT_TRUE ? "true" : "false");
782                 }
783         } else {
784 -               if (con->conf.log_condition_handling) {
785 +               if (con->conf.log_condition_cache_handling) {
786                         log_error_write(srv, __FILE__, __LINE__, "dss", dc->context_ndx,
787                                         "(cached) result:",
788                                         caches[dc->context_ndx].result == COND_RESULT_TRUE ? "true" : "false");
789 @@ -423,9 +443,6 @@
790  }
791  
792  int config_check_cond(server *srv, connection *con, data_config *dc) {
793 -       if (con->conf.log_condition_handling) {
794 -               log_error_write(srv, __FILE__, __LINE__,  "s",  "=== start of condition block ===");
795 -       }
796         return (config_check_cond_cached(srv, con, dc) == COND_RESULT_TRUE);
797  }
798  
799 @@ -443,3 +460,85 @@
800         return 1;
801  }
802  
803 +/* return <0 on error
804 + * return 0-x if matched (and replaced)
805 + */
806 +int config_exec_pcre_keyvalue_buffer(connection *con, pcre_keyvalue_buffer *kvb, data_config *context, buffer *match_buf, buffer *result)
807 +{
808 +#ifdef HAVE_PCRE_H
809 +       pcre *match;
810 +       pcre_extra *extra;
811 +       const char *pattern;
812 +       size_t pattern_len;
813 +       int n;
814 +       size_t i;
815 +       pcre_keyvalue *kv;
816 +# define N 10
817 +       int ovec[N * 3];
818 +
819 +       for (i = 0; i < kvb->used; i++) {
820 +               kv = kvb->kv[i];
821 +
822 +               match       = kv->key;
823 +               extra       = kv->key_extra;
824 +               pattern     = kv->value->ptr;
825 +               pattern_len = kv->value->used - 1;
826 +
827 +               if ((n = pcre_exec(match, extra, match_buf->ptr, match_buf->used - 1, 0, 0, ovec, 3 * N)) < 0) {
828 +                       if (n != PCRE_ERROR_NOMATCH) {
829 +                               return n;
830 +                       }
831 +               } else {
832 +                       const char **list;
833 +                       size_t start, end;
834 +                       size_t k;
835 +
836 +                       /* it matched */
837 +                       pcre_get_substring_list(match_buf->ptr, ovec, n, &list);
838 +
839 +                       /* search for $[0-9] */
840 +
841 +                       buffer_reset(result);
842 +
843 +                       start = 0; end = pattern_len;
844 +                       for (k = 0; k < pattern_len; k++) {
845 +                               if ((pattern[k] == '$' || pattern[k] == '%') &&
846 +                                   isdigit((unsigned char)pattern[k + 1])) {
847 +                                       /* got one */
848 +
849 +                                       size_t num = pattern[k + 1] - '0';
850 +
851 +                                       end = k;
852 +
853 +                                       buffer_append_string_len(result, pattern + start, end - start);
854 +
855 +                                       if (pattern[k] == '$') {
856 +                                               /* n is always > 0 */
857 +                                               if (num < (size_t)n) {
858 +                                                       buffer_append_string(result, list[num]);
859 +                                               }
860 +                                       } else {
861 +                                               config_append_cond_match_buffer(con, context, result, num);
862 +                                       }
863 +
864 +                                       k++;
865 +                                       start = k + 1;
866 +                               }
867 +                       }
868 +
869 +                       buffer_append_string_len(result, pattern + start, pattern_len - start);
870 +
871 +                       pcre_free(list);
872 +
873 +                       return i;
874 +               }
875 +       }
876 +
877 +       return PCRE_ERROR_NOMATCH;
878 +#undef N
879 +#else
880 +       UNUSED(kvb);
881 +       return -2;
882 +#endif
883 +}
884 +
885
886 Property changes on: src/configfile-glue.c
887 ___________________________________________________________________
888 Name: svn:eol-style
889    + native
890
891 Index: src/fdevent.h
892 ===================================================================
893 --- src/fdevent.h       (.../tags/lighttpd-1.4.11)      (revision 1159)
894 +++ src/fdevent.h       (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
895 @@ -17,13 +17,13 @@
896  # include <sys/epoll.h>
897  #endif
898  
899 -/* MacOS 10.3.x has poll.h under /usr/include/, all other unixes 
900 +/* MacOS 10.3.x has poll.h under /usr/include/, all other unixes
901   * under /usr/include/sys/ */
902  #if defined HAVE_POLL && (defined(HAVE_SYS_POLL_H) || defined(HAVE_POLL_H))
903  # define USE_POLL
904  # ifdef HAVE_POLL_H
905  #  include <poll.h>
906 -# else 
907 +# else
908  #  include <sys/poll.h>
909  # endif
910  # if defined HAVE_SIGTIMEDWAIT && defined(__linux__)
911 @@ -31,9 +31,11 @@
912  #  include <signal.h>
913  # endif
914  #endif
915 -
916 +#ifdef _WIN32
917 +# define HAVE_SELECT
918 +#endif
919  #if defined HAVE_SELECT
920 -# ifdef __WIN32
921 +# ifdef _WIN32
922  #  include <winsock2.h>
923  # endif
924  # define USE_SELECT
925 @@ -67,14 +69,14 @@
926  #define FDEVENT_HUP    BV(4)
927  #define FDEVENT_NVAL   BV(5)
928  
929 -typedef enum { FD_EVENT_TYPE_UNSET = -1, 
930 -               FD_EVENT_TYPE_CONNECTION, 
931 -               FD_EVENT_TYPE_FCGI_CONNECTION, 
932 -               FD_EVENT_TYPE_DIRWATCH, 
933 -               FD_EVENT_TYPE_CGI_CONNECTION 
934 +typedef enum { FD_EVENT_TYPE_UNSET = -1,
935 +               FD_EVENT_TYPE_CONNECTION,
936 +               FD_EVENT_TYPE_FCGI_CONNECTION,
937 +               FD_EVENT_TYPE_DIRWATCH,
938 +               FD_EVENT_TYPE_CGI_CONNECTION
939  } fd_event_t;
940  
941 -typedef enum { FDEVENT_HANDLER_UNSET, 
942 +typedef enum { FDEVENT_HANDLER_UNSET,
943                 FDEVENT_HANDLER_SELECT,
944                 FDEVENT_HANDLER_POLL,
945                 FDEVENT_HANDLER_LINUX_RTSIG,
946 @@ -86,7 +88,7 @@
947  
948  /**
949   * a mapping from fd to connection structure
950 - * 
951 + *
952   */
953  typedef struct {
954         int fd;                  /**< the fd */
955 @@ -98,41 +100,41 @@
956  
957  typedef struct {
958         fd_conn *ptr;
959 -       
960 +
961         size_t size;
962         size_t used;
963  } fd_conn_buffer;
964  
965  /**
966   * array of unused fd's
967 - * 
968 + *
969   */
970  
971  typedef struct _fdnode {
972         fdevent_handler handler;
973         void *ctx;
974         int fd;
975 -       
976 +
977         struct _fdnode *prev, *next;
978  } fdnode;
979  
980  typedef struct {
981         int *ptr;
982 -       
983 +
984         size_t used;
985         size_t size;
986  } buffer_int;
987  
988  /**
989   * fd-event handler for select(), poll() and rt-signals on Linux 2.4
990 - * 
991 + *
992   */
993  typedef struct fdevents {
994         fdevent_handler_t type;
995 -       
996 +
997         fdnode **fdarray;
998         size_t maxfds;
999 -       
1000 +
1001  #ifdef USE_LINUX_SIGIO
1002         int in_sigio;
1003         int signum;
1004 @@ -146,21 +148,21 @@
1005  #endif
1006  #ifdef USE_POLL
1007         struct pollfd *pollfds;
1008 -       
1009 +
1010         size_t size;
1011         size_t used;
1012 -       
1013 +
1014         buffer_int unused;
1015  #endif
1016  #ifdef USE_SELECT
1017         fd_set select_read;
1018         fd_set select_write;
1019         fd_set select_error;
1020 -       
1021 +
1022         fd_set select_set_read;
1023         fd_set select_set_write;
1024         fd_set select_set_error;
1025 -       
1026 +
1027         int select_max_fd;
1028  #endif
1029  #ifdef USE_SOLARIS_DEVPOLL
1030 @@ -177,16 +179,16 @@
1031  #endif
1032         int (*reset)(struct fdevents *ev);
1033         void (*free)(struct fdevents *ev);
1034 -       
1035 +
1036         int (*event_add)(struct fdevents *ev, int fde_ndx, int fd, int events);
1037         int (*event_del)(struct fdevents *ev, int fde_ndx, int fd);
1038         int (*event_get_revent)(struct fdevents *ev, size_t ndx);
1039         int (*event_get_fd)(struct fdevents *ev, size_t ndx);
1040 -       
1041 +
1042         int (*event_next_fdndx)(struct fdevents *ev, int ndx);
1043 -       
1044 +
1045         int (*poll)(struct fdevents *ev, int timeout_ms);
1046 -       
1047 +
1048         int (*fcntl_set)(struct fdevents *ev, int fd);
1049  } fdevents;
1050  
1051
1052 Property changes on: src/fdevent.h
1053 ___________________________________________________________________
1054 Name: svn:eol-style
1055    + native
1056
1057 Index: src/mod_cgi.c
1058 ===================================================================
1059 --- src/mod_cgi.c       (.../tags/lighttpd-1.4.11)      (revision 1159)
1060 +++ src/mod_cgi.c       (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
1061 @@ -1,21 +1,8 @@
1062  #include <sys/types.h>
1063 -#ifdef __WIN32
1064 -#include <winsock2.h>
1065 -#else
1066 -#include <sys/socket.h>
1067 -#include <sys/wait.h>
1068 -#include <sys/mman.h>
1069  
1070 -#include <netinet/in.h>
1071 -
1072 -#include <arpa/inet.h>
1073 -#endif
1074 -
1075 -#include <unistd.h>
1076  #include <errno.h>
1077  #include <stdlib.h>
1078  #include <string.h>
1079 -#include <fdevent.h>
1080  #include <signal.h>
1081  #include <ctype.h>
1082  #include <assert.h>
1083 @@ -29,9 +16,16 @@
1084  #include "connections.h"
1085  #include "joblist.h"
1086  #include "http_chunk.h"
1087 +#include "fdevent.h"
1088  
1089  #include "plugin.h"
1090  
1091 +#include "sys-files.h"
1092 +#include "sys-mmap.h"
1093 +#include "sys-socket.h"
1094 +#include "sys-strings.h"
1095 +#include "sys-process.h"
1096 +
1097  #ifdef HAVE_SYS_FILIO_H
1098  # include <sys/filio.h>
1099  #endif
1100 @@ -40,11 +34,12 @@
1101  
1102  typedef struct {
1103         char **ptr;
1104 -       
1105 +
1106         size_t size;
1107         size_t used;
1108  } char_array;
1109  
1110 +#define pid_t int
1111  typedef struct {
1112         pid_t *ptr;
1113         size_t used;
1114 @@ -58,23 +53,23 @@
1115  typedef struct {
1116         PLUGIN_DATA;
1117         buffer_pid_t cgi_pid;
1118 -       
1119 +
1120         buffer *tmp_buf;
1121         buffer *parse_response;
1122 -       
1123 +
1124         plugin_config **config_storage;
1125 -       
1126 -       plugin_config conf; 
1127 +
1128 +       plugin_config conf;
1129  } plugin_data;
1130  
1131  typedef struct {
1132         pid_t pid;
1133         int fd;
1134         int fde_ndx; /* index into the fd-event buffer */
1135 -       
1136 +
1137         connection *remote_conn;  /* dumb pointer */
1138         plugin_data *plugin_data; /* dumb pointer */
1139 -       
1140 +
1141         buffer *response;
1142         buffer *response_header;
1143  } handler_ctx;
1144 @@ -83,17 +78,17 @@
1145         handler_ctx *hctx = calloc(1, sizeof(*hctx));
1146  
1147         assert(hctx);
1148 -       
1149 +
1150         hctx->response = buffer_init();
1151         hctx->response_header = buffer_init();
1152 -       
1153 +
1154         return hctx;
1155  }
1156  
1157  static void cgi_handler_ctx_free(handler_ctx *hctx) {
1158         buffer_free(hctx->response);
1159         buffer_free(hctx->response_header);
1160 -       
1161 +
1162         free(hctx);
1163  }
1164  
1165 @@ -101,14 +96,14 @@
1166  
1167  INIT_FUNC(mod_cgi_init) {
1168         plugin_data *p;
1169 -       
1170 +
1171         p = calloc(1, sizeof(*p));
1172  
1173         assert(p);
1174 -       
1175 +
1176         p->tmp_buf = buffer_init();
1177         p->parse_response = buffer_init();
1178 -       
1179 +
1180         return p;
1181  }
1182  
1183 @@ -116,62 +111,62 @@
1184  FREE_FUNC(mod_cgi_free) {
1185         plugin_data *p = p_d;
1186         buffer_pid_t *r = &(p->cgi_pid);
1187 -       
1188 +
1189         UNUSED(srv);
1190 -       
1191 +
1192         if (p->config_storage) {
1193                 size_t i;
1194                 for (i = 0; i < srv->config_context->used; i++) {
1195                         plugin_config *s = p->config_storage[i];
1196 -                       
1197 +
1198                         array_free(s->cgi);
1199 -                       
1200 +
1201                         free(s);
1202                 }
1203                 free(p->config_storage);
1204         }
1205 -       
1206  
1207 +
1208         if (r->ptr) free(r->ptr);
1209 -       
1210 +
1211         buffer_free(p->tmp_buf);
1212         buffer_free(p->parse_response);
1213 -       
1214 +
1215         free(p);
1216 -       
1217 +
1218         return HANDLER_GO_ON;
1219  }
1220  
1221  SETDEFAULTS_FUNC(mod_fastcgi_set_defaults) {
1222         plugin_data *p = p_d;
1223         size_t i = 0;
1224 -       
1225 -       config_values_t cv[] = { 
1226 +
1227 +       config_values_t cv[] = {
1228                 { "cgi.assign",                  NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
1229                 { NULL,                          NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET}
1230         };
1231  
1232         if (!p) return HANDLER_ERROR;
1233 -       
1234 +
1235         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
1236 -       
1237 +
1238         for (i = 0; i < srv->config_context->used; i++) {
1239                 plugin_config *s;
1240 -               
1241 +
1242                 s = calloc(1, sizeof(plugin_config));
1243                 assert(s);
1244 -               
1245 +
1246                 s->cgi    = array_init();
1247 -               
1248 +
1249                 cv[0].destination = s->cgi;
1250 -               
1251 +
1252                 p->config_storage[i] = s;
1253 -       
1254 +
1255                 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
1256                         return HANDLER_ERROR;
1257                 }
1258         }
1259 -       
1260 +
1261         return HANDLER_GO_ON;
1262  }
1263  
1264 @@ -180,13 +175,13 @@
1265         int m = -1;
1266         size_t i;
1267         buffer_pid_t *r = &(p->cgi_pid);
1268 -       
1269 +
1270         UNUSED(srv);
1271  
1272         for (i = 0; i < r->used; i++) {
1273                 if (r->ptr[i] > m) m = r->ptr[i];
1274         }
1275 -       
1276 +
1277         if (r->size == 0) {
1278                 r->size = 16;
1279                 r->ptr = malloc(sizeof(*r->ptr) * r->size);
1280 @@ -194,31 +189,31 @@
1281                 r->size += 16;
1282                 r->ptr = realloc(r->ptr, sizeof(*r->ptr) * r->size);
1283         }
1284 -       
1285 +
1286         r->ptr[r->used++] = pid;
1287 -       
1288 +
1289         return m;
1290  }
1291  
1292  static int cgi_pid_del(server *srv, plugin_data *p, pid_t pid) {
1293         size_t i;
1294         buffer_pid_t *r = &(p->cgi_pid);
1295 -       
1296 +
1297         UNUSED(srv);
1298  
1299         for (i = 0; i < r->used; i++) {
1300                 if (r->ptr[i] == pid) break;
1301         }
1302 -       
1303 +
1304         if (i != r->used) {
1305                 /* found */
1306 -               
1307 +
1308                 if (i != r->used - 1) {
1309                         r->ptr[i] = r->ptr[r->used - 1];
1310                 }
1311                 r->used--;
1312         }
1313 -       
1314 +
1315         return 0;
1316  }
1317  
1318 @@ -226,32 +221,32 @@
1319         char *ns;
1320         const char *s;
1321         int line = 0;
1322 -       
1323 +
1324         UNUSED(srv);
1325 -       
1326 +
1327         buffer_copy_string_buffer(p->parse_response, in);
1328 -       
1329 -       for (s = p->parse_response->ptr; 
1330 -            NULL != (ns = (eol == EOL_RN ? strstr(s, "\r\n") : strchr(s, '\n'))); 
1331 +
1332 +       for (s = p->parse_response->ptr;
1333 +            NULL != (ns = (eol == EOL_RN ? strstr(s, "\r\n") : strchr(s, '\n')));
1334              s = ns + (eol == EOL_RN ? 2 : 1), line++) {
1335                 const char *key, *value;
1336                 int key_len;
1337                 data_string *ds;
1338 -               
1339 +
1340                 ns[0] = '\0';
1341 -               
1342 -               if (line == 0 && 
1343 +
1344 +               if (line == 0 &&
1345                     0 == strncmp(s, "HTTP/1.", 7)) {
1346                         /* non-parsed header ... we parse them anyway */
1347 -                       
1348 +
1349                         if ((s[7] == '1' ||
1350                              s[7] == '0') &&
1351                             s[8] == ' ') {
1352                                 int status;
1353                                 /* after the space should be a status code for us */
1354 -                               
1355 +
1356                                 status = strtol(s+9, NULL, 10);
1357 -                               
1358 +
1359                                 if (con->http_status >= 100 &&
1360                                     con->http_status < 1000) {
1361                                         /* we expected 3 digits and didn't got them */
1362 @@ -260,27 +255,27 @@
1363                                 }
1364                         }
1365                 } else {
1366 -               
1367 +
1368                         key = s;
1369                         if (NULL == (value = strchr(s, ':'))) {
1370                                 /* we expect: "<key>: <value>\r\n" */
1371                                 continue;
1372                         }
1373 -                       
1374 +
1375                         key_len = value - key;
1376                         value += 1;
1377 -                       
1378 +
1379                         /* skip LWS */
1380                         while (*value == ' ' || *value == '\t') value++;
1381 -                       
1382 +
1383                         if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
1384                                 ds = data_response_init();
1385                         }
1386                         buffer_copy_string_len(ds->key, key, key_len);
1387                         buffer_copy_string(ds->value, value);
1388 -                       
1389 +
1390                         array_insert_unique(con->response.headers, (data_unset *)ds);
1391 -                       
1392 +
1393                         switch(key_len) {
1394                         case 4:
1395                                 if (0 == strncasecmp(key, "Date", key_len)) {
1396 @@ -315,13 +310,13 @@
1397                         }
1398                 }
1399         }
1400 -       
1401 +
1402         /* CGI/1.1 rev 03 - 7.2.1.2 */
1403         if ((con->parsed_response & HTTP_LOCATION) &&
1404             !(con->parsed_response & HTTP_STATUS)) {
1405                 con->http_status = 302;
1406         }
1407 -       
1408 +
1409         return 0;
1410  }
1411  
1412 @@ -329,10 +324,10 @@
1413  static int cgi_demux_response(server *srv, handler_ctx *hctx) {
1414         plugin_data *p    = hctx->plugin_data;
1415         connection  *con  = hctx->remote_conn;
1416 -       
1417 +
1418         while(1) {
1419                 int n;
1420 -               
1421 +
1422                 buffer_prepare_copy(hctx->response, 1024);
1423                 if (-1 == (n = read(hctx->fd, hctx->response->ptr, hctx->response->size - 1))) {
1424                         if (errno == EAGAIN || errno == EINTR) {
1425 @@ -343,125 +338,125 @@
1426                         log_error_write(srv, __FILE__, __LINE__, "sdd", strerror(errno), con->fd, hctx->fd);
1427                         return FDEVENT_HANDLED_ERROR;
1428                 }
1429 -               
1430 +
1431                 if (n == 0) {
1432                         /* read finished */
1433 -                       
1434 +
1435                         con->file_finished = 1;
1436 -                       
1437 +
1438                         /* send final chunk */
1439                         http_chunk_append_mem(srv, con, NULL, 0);
1440                         joblist_append(srv, con);
1441 -                       
1442 +
1443                         return FDEVENT_HANDLED_FINISHED;
1444                 }
1445 -               
1446 +
1447                 hctx->response->ptr[n] = '\0';
1448                 hctx->response->used = n+1;
1449 -               
1450 +
1451                 /* split header from body */
1452 -               
1453 +
1454                 if (con->file_started == 0) {
1455                         char *c;
1456                         int in_header = 0;
1457                         int header_end = 0;
1458                         int cp, eol = EOL_UNSET;
1459                         size_t used = 0;
1460 -                       
1461 +
1462                         buffer_append_string_buffer(hctx->response_header, hctx->response);
1463 -                       
1464 +
1465                         /* nph (non-parsed headers) */
1466                         if (0 == strncmp(hctx->response_header->ptr, "HTTP/1.", 7)) in_header = 1;
1467 -                       
1468 +
1469                         /* search for the \r\n\r\n or \n\n in the string */
1470                         for (c = hctx->response_header->ptr, cp = 0, used = hctx->response_header->used - 1; used; c++, cp++, used--) {
1471                                 if (*c == ':') in_header = 1;
1472                                 else if (*c == '\n') {
1473                                         if (in_header == 0) {
1474                                                 /* got a response without a response header */
1475 -                                               
1476 +
1477                                                 c = NULL;
1478                                                 header_end = 1;
1479                                                 break;
1480                                         }
1481 -                                       
1482 +
1483                                         if (eol == EOL_UNSET) eol = EOL_N;
1484 -                                       
1485 +
1486                                         if (*(c+1) == '\n') {
1487                                                 header_end = 1;
1488                                                 break;
1489                                         }
1490 -                                       
1491 +
1492                                 } else if (used > 1 && *c == '\r' && *(c+1) == '\n') {
1493                                         if (in_header == 0) {
1494                                                 /* got a response without a response header */
1495 -                                               
1496 +
1497                                                 c = NULL;
1498                                                 header_end = 1;
1499                                                 break;
1500                                         }
1501 -                                       
1502 +
1503                                         if (eol == EOL_UNSET) eol = EOL_RN;
1504 -                                       
1505 +
1506                                         if (used > 3 &&
1507 -                                           *(c+2) == '\r' && 
1508 +                                           *(c+2) == '\r' &&
1509                                             *(c+3) == '\n') {
1510                                                 header_end = 1;
1511                                                 break;
1512                                         }
1513 -                                       
1514 +
1515                                         /* skip the \n */
1516                                         c++;
1517                                         cp++;
1518                                         used--;
1519                                 }
1520                         }
1521 -                       
1522 +
1523                         if (header_end) {
1524                                 if (c == NULL) {
1525                                         /* no header, but a body */
1526 -                                       
1527 +
1528                                         if (con->request.http_version == HTTP_VERSION_1_1) {
1529                                                 con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
1530                                         }
1531 -                                       
1532 +
1533                                         http_chunk_append_mem(srv, con, hctx->response_header->ptr, hctx->response_header->used);
1534                                         joblist_append(srv, con);
1535                                 } else {
1536                                         size_t hlen = c - hctx->response_header->ptr + (eol == EOL_RN ? 4 : 2);
1537                                         size_t blen = hctx->response_header->used - hlen - 1;
1538 -                               
1539 +
1540                                         /* a small hack: terminate after at the second \r */
1541                                         hctx->response_header->used = hlen + 1 - (eol == EOL_RN ? 2 : 1);
1542                                         hctx->response_header->ptr[hlen - (eol == EOL_RN ? 2 : 1)] = '\0';
1543 -                               
1544 +
1545                                         /* parse the response header */
1546                                         cgi_response_parse(srv, con, p, hctx->response_header, eol);
1547 -                                       
1548 +
1549                                         /* enable chunked-transfer-encoding */
1550                                         if (con->request.http_version == HTTP_VERSION_1_1 &&
1551                                             !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
1552                                                 con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
1553                                         }
1554 -                                       
1555 +
1556                                         if ((hctx->response->used != hlen) && blen > 0) {
1557                                                 http_chunk_append_mem(srv, con, c + (eol == EOL_RN ? 4: 2), blen + 1);
1558                                                 joblist_append(srv, con);
1559                                         }
1560                                 }
1561 -                               
1562 +
1563                                 con->file_started = 1;
1564                         }
1565                 } else {
1566                         http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used);
1567                         joblist_append(srv, con);
1568                 }
1569 -               
1570 -#if 0          
1571 +
1572 +#if 0
1573                 log_error_write(srv, __FILE__, __LINE__, "ddss", con->fd, hctx->fd, connection_get_state(con->state), b->ptr);
1574  #endif
1575         }
1576 -       
1577 +
1578         return FDEVENT_HANDLED_NOT_FINISHED;
1579  }
1580  
1581 @@ -470,45 +465,46 @@
1582         pid_t pid;
1583         plugin_data *p;
1584         connection  *con;
1585 -       
1586 +
1587         if (NULL == hctx) return HANDLER_GO_ON;
1588 -       
1589 +
1590         p    = hctx->plugin_data;
1591         con  = hctx->remote_conn;
1592 -       
1593 +
1594         if (con->mode != p->id) return HANDLER_GO_ON;
1595  
1596 -#ifndef __WIN32
1597 -       
1598 +#ifndef _WIN32
1599 +
1600         /* the connection to the browser went away, but we still have a connection
1601 -        * to the CGI script 
1602 +        * to the CGI script
1603          *
1604          * close cgi-connection
1605          */
1606 -       
1607 +
1608         if (hctx->fd != -1) {
1609                 /* close connection to the cgi-script */
1610                 fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
1611                 fdevent_unregister(srv->ev, hctx->fd);
1612 -               
1613 +
1614                 if (close(hctx->fd)) {
1615                         log_error_write(srv, __FILE__, __LINE__, "sds", "cgi close failed ", hctx->fd, strerror(errno));
1616                 }
1617 -               
1618 +
1619                 hctx->fd = -1;
1620                 hctx->fde_ndx = -1;
1621         }
1622 -       
1623 +
1624         pid = hctx->pid;
1625 -       
1626 +
1627         con->plugin_ctx[p->id] = NULL;
1628 -       
1629 +
1630         /* is this a good idea ? */
1631         cgi_handler_ctx_free(hctx);
1632 -       
1633 +
1634         /* if waitpid hasn't been called by response.c yet, do it here */
1635         if (pid) {
1636                 /* check if the CGI-script is already gone */
1637 +#ifndef _WIN32
1638                 switch(waitpid(pid, &status, WNOHANG)) {
1639                 case 0:
1640                         /* not finished yet */
1641 @@ -519,19 +515,19 @@
1642                 case -1:
1643                         /* */
1644                         if (errno == EINTR) break;
1645 -                       
1646 -                       /* 
1647 -                        * errno == ECHILD happens if _subrequest catches the process-status before 
1648 +
1649 +                       /*
1650 +                        * errno == ECHILD happens if _subrequest catches the process-status before
1651                          * we have read the response of the cgi process
1652 -                        * 
1653 +                        *
1654                          * -> catch status
1655                          * -> WAIT_FOR_EVENT
1656                          * -> read response
1657                          * -> we get here with waitpid == ECHILD
1658 -                        * 
1659 +                        *
1660                          */
1661                         if (errno == ECHILD) return HANDLER_GO_ON;
1662 -                       
1663 +
1664                         log_error_write(srv, __FILE__, __LINE__, "ss", "waitpid failed: ", strerror(errno));
1665                         return HANDLER_ERROR;
1666                 default:
1667 @@ -541,13 +537,13 @@
1668                                 con->http_status = 500;
1669                                 con->mode = DIRECT;
1670                         }
1671 -                               
1672 +
1673                         if (WIFEXITED(status)) {
1674  #if 0
1675                                 log_error_write(srv, __FILE__, __LINE__, "sd", "(debug) cgi exited fine, pid:", pid);
1676  #endif
1677                                 pid = 0;
1678 -                               
1679 +
1680                                 return HANDLER_GO_ON;
1681                         } else {
1682                                 log_error_write(srv, __FILE__, __LINE__, "sd", "cgi died, pid:", pid);
1683 @@ -555,20 +551,20 @@
1684                                 return HANDLER_GO_ON;
1685                         }
1686                 }
1687 -               
1688 -       
1689 +
1690 +
1691                 kill(pid, SIGTERM);
1692 -               
1693 +#endif
1694                 /* cgi-script is still alive, queue the PID for removal */
1695                 cgi_pid_add(srv, p, pid);
1696         }
1697 -#endif 
1698 +#endif
1699         return HANDLER_GO_ON;
1700  }
1701  
1702  static handler_t cgi_connection_close_callback(server *srv, connection *con, void *p_d) {
1703         plugin_data *p = p_d;
1704 -       
1705 +
1706         return cgi_connection_close(srv, con->plugin_ctx[p->id]);
1707  }
1708  
1709 @@ -577,43 +573,43 @@
1710         server      *srv  = (server *)s;
1711         handler_ctx *hctx = ctx;
1712         connection  *con  = hctx->remote_conn;
1713 -       
1714 +
1715         joblist_append(srv, con);
1716 -       
1717 +
1718         if (hctx->fd == -1) {
1719                 log_error_write(srv, __FILE__, __LINE__, "ddss", con->fd, hctx->fd, connection_get_state(con->state), "invalid cgi-fd");
1720 -               
1721 +
1722                 return HANDLER_ERROR;
1723         }
1724 -       
1725 +
1726         if (revents & FDEVENT_IN) {
1727                 switch (cgi_demux_response(srv, hctx)) {
1728                 case FDEVENT_HANDLED_NOT_FINISHED:
1729                         break;
1730                 case FDEVENT_HANDLED_FINISHED:
1731                         /* we are done */
1732 -                       
1733 +
1734  #if 0
1735                         log_error_write(srv, __FILE__, __LINE__, "ddss", con->fd, hctx->fd, connection_get_state(con->state), "finished");
1736  #endif
1737                         cgi_connection_close(srv, hctx);
1738 -                       
1739 -                       /* if we get a IN|HUP and have read everything don't exec the close twice */ 
1740 +
1741 +                       /* if we get a IN|HUP and have read everything don't exec the close twice */
1742                         return HANDLER_FINISHED;
1743                 case FDEVENT_HANDLED_ERROR:
1744                         connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
1745                         con->http_status = 500;
1746                         con->mode = DIRECT;
1747 -                       
1748 +
1749                         log_error_write(srv, __FILE__, __LINE__, "s", "demuxer failed: ");
1750                         break;
1751                 }
1752         }
1753 -       
1754 +
1755         if (revents & FDEVENT_OUT) {
1756                 /* nothing to do */
1757         }
1758 -       
1759 +
1760         /* perhaps this issue is already handled */
1761         if (revents & FDEVENT_HUP) {
1762                 /* check if we still have a unfinished header package which is a body in reality */
1763 @@ -623,54 +619,54 @@
1764                         http_chunk_append_mem(srv, con, hctx->response_header->ptr, hctx->response_header->used);
1765                         joblist_append(srv, con);
1766                 }
1767 -               
1768 +
1769                 if (con->file_finished == 0) {
1770                         http_chunk_append_mem(srv, con, NULL, 0);
1771                         joblist_append(srv, con);
1772                 }
1773 -               
1774 +
1775                 con->file_finished = 1;
1776 -               
1777 +
1778                 if (chunkqueue_is_empty(con->write_queue)) {
1779                         /* there is nothing left to write */
1780                         connection_set_state(srv, con, CON_STATE_RESPONSE_END);
1781                 } else {
1782                         /* used the write-handler to finish the request on demand */
1783 -                       
1784 +
1785                 }
1786 -               
1787 +
1788  # if 0
1789                 log_error_write(srv, __FILE__, __LINE__, "sddd", "got HUP from cgi", con->fd, hctx->fd, revents);
1790  # endif
1791 -               
1792 +
1793                 /* rtsigs didn't liked the close */
1794                 cgi_connection_close(srv, hctx);
1795         } else if (revents & FDEVENT_ERR) {
1796                 con->file_finished = 1;
1797 -               
1798 +
1799                 /* kill all connections to the cgi process */
1800                 cgi_connection_close(srv, hctx);
1801  #if 1
1802                 log_error_write(srv, __FILE__, __LINE__, "s", "cgi-FDEVENT_ERR");
1803 -#endif                 
1804 +#endif
1805                 return HANDLER_ERROR;
1806         }
1807 -       
1808 +
1809         return HANDLER_FINISHED;
1810  }
1811  
1812  
1813  static int cgi_env_add(char_array *env, const char *key, size_t key_len, const char *val, size_t val_len) {
1814         char *dst;
1815 -       
1816 +
1817         if (!key || !val) return -1;
1818 -       
1819 +
1820         dst = malloc(key_len + val_len + 3);
1821         memcpy(dst, key, key_len);
1822         dst[key_len] = '=';
1823         /* add the \0 from the value */
1824         memcpy(dst + key_len + 1, val, val_len + 1);
1825 -       
1826 +
1827         if (env->size == 0) {
1828                 env->size = 16;
1829                 env->ptr = malloc(env->size * sizeof(*env->ptr));
1830 @@ -678,45 +674,45 @@
1831                 env->size += 16;
1832                 env->ptr = realloc(env->ptr, env->size * sizeof(*env->ptr));
1833         }
1834 -       
1835 +
1836         env->ptr[env->used++] = dst;
1837 -       
1838 +
1839         return 0;
1840  }
1841  
1842  static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *cgi_handler) {
1843         pid_t pid;
1844 -       
1845 +
1846  #ifdef HAVE_IPV6
1847         char b2[INET6_ADDRSTRLEN + 1];
1848  #endif
1849 -       
1850 +
1851         int to_cgi_fds[2];
1852         int from_cgi_fds[2];
1853         struct stat st;
1854 -       
1855 -#ifndef __WIN32        
1856 -       
1857 +
1858 +#ifndef _WIN32
1859 +
1860         if (cgi_handler->used > 1) {
1861                 /* stat the exec file */
1862                 if (-1 == (stat(cgi_handler->ptr, &st))) {
1863 -                       log_error_write(srv, __FILE__, __LINE__, "sbss", 
1864 +                       log_error_write(srv, __FILE__, __LINE__, "sbss",
1865                                         "stat for cgi-handler", cgi_handler,
1866                                         "failed:", strerror(errno));
1867                         return -1;
1868                 }
1869         }
1870 -       
1871 +
1872         if (pipe(to_cgi_fds)) {
1873                 log_error_write(srv, __FILE__, __LINE__, "ss", "pipe failed:", strerror(errno));
1874                 return -1;
1875         }
1876 -       
1877 +
1878         if (pipe(from_cgi_fds)) {
1879                 log_error_write(srv, __FILE__, __LINE__, "ss", "pipe failed:", strerror(errno));
1880                 return -1;
1881         }
1882 -       
1883 +
1884         /* fork, execve */
1885         switch (pid = fork()) {
1886         case 0: {
1887 @@ -730,22 +726,22 @@
1888                 char *c;
1889                 const char *s;
1890                 server_socket *srv_sock = con->srv_socket;
1891 -               
1892 +
1893                 /* move stdout to from_cgi_fd[1] */
1894                 close(STDOUT_FILENO);
1895                 dup2(from_cgi_fds[1], STDOUT_FILENO);
1896                 close(from_cgi_fds[1]);
1897                 /* not needed */
1898                 close(from_cgi_fds[0]);
1899 -               
1900 +
1901                 /* move the stdin to to_cgi_fd[0] */
1902                 close(STDIN_FILENO);
1903                 dup2(to_cgi_fds[0], STDIN_FILENO);
1904                 close(to_cgi_fds[0]);
1905                 /* not needed */
1906                 close(to_cgi_fds[1]);
1907 -               
1908 -               /* HACK: 
1909 +
1910 +               /* HACK:
1911                  * this is not nice, but it works
1912                  *
1913                  * we feed the stderr of the CGI to our errorlog, if possible
1914 @@ -754,20 +750,20 @@
1915                         close(STDERR_FILENO);
1916                         dup2(srv->errorlog_fd, STDERR_FILENO);
1917                 }
1918 -               
1919 +
1920                 /* create environment */
1921                 env.ptr = NULL;
1922                 env.size = 0;
1923                 env.used = 0;
1924 -               
1925 +
1926                 cgi_env_add(&env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_NAME"/"PACKAGE_VERSION));
1927  
1928                 if (!buffer_is_empty(con->server_name)) {
1929                         cgi_env_add(&env, CONST_STR_LEN("SERVER_NAME"), CONST_BUF_LEN(con->server_name));
1930                 } else {
1931  #ifdef HAVE_IPV6
1932 -                       s = inet_ntop(srv_sock->addr.plain.sa_family, 
1933 -                                     srv_sock->addr.plain.sa_family == AF_INET6 ? 
1934 +                       s = inet_ntop(srv_sock->addr.plain.sa_family,
1935 +                                     srv_sock->addr.plain.sa_family == AF_INET6 ?
1936                                       (const void *) &(srv_sock->addr.ipv6.sin6_addr) :
1937                                       (const void *) &(srv_sock->addr.ipv4.sin_addr),
1938                                       b2, sizeof(b2)-1);
1939 @@ -779,10 +775,10 @@
1940                 cgi_env_add(&env, CONST_STR_LEN("GATEWAY_INTERFACE"), CONST_STR_LEN("CGI/1.1"));
1941  
1942                 s = get_http_version_name(con->request.http_version);
1943 -               
1944 +
1945                 cgi_env_add(&env, CONST_STR_LEN("SERVER_PROTOCOL"), s, strlen(s));
1946 -               
1947 -               ltostr(buf, 
1948 +
1949 +               ltostr(buf,
1950  #ifdef HAVE_IPV6
1951                         ntohs(srv_sock->addr.plain.sa_family == AF_INET6 ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port)
1952  #else
1953 @@ -790,10 +786,10 @@
1954  #endif
1955                         );
1956                 cgi_env_add(&env, CONST_STR_LEN("SERVER_PORT"), buf, strlen(buf));
1957 -               
1958 +
1959  #ifdef HAVE_IPV6
1960 -               s = inet_ntop(srv_sock->addr.plain.sa_family, 
1961 -                             srv_sock->addr.plain.sa_family == AF_INET6 ? 
1962 +               s = inet_ntop(srv_sock->addr.plain.sa_family,
1963 +                             srv_sock->addr.plain.sa_family == AF_INET6 ?
1964                               (const void *) &(srv_sock->addr.ipv6.sin6_addr) :
1965                               (const void *) &(srv_sock->addr.ipv4.sin_addr),
1966                               b2, sizeof(b2)-1);
1967 @@ -811,15 +807,18 @@
1968                 cgi_env_add(&env, CONST_STR_LEN("REDIRECT_STATUS"), CONST_STR_LEN("200"));
1969                 if (!buffer_is_empty(con->uri.query)) {
1970                         cgi_env_add(&env, CONST_STR_LEN("QUERY_STRING"), CONST_BUF_LEN(con->uri.query));
1971 +               } else {
1972 +                       /* set a empty QUERY_STRING */
1973 +                       cgi_env_add(&env, CONST_STR_LEN("QUERY_STRING"), CONST_STR_LEN(""));
1974                 }
1975                 if (!buffer_is_empty(con->request.orig_uri)) {
1976                         cgi_env_add(&env, CONST_STR_LEN("REQUEST_URI"), CONST_BUF_LEN(con->request.orig_uri));
1977                 }
1978 -               
1979 -               
1980 +
1981 +
1982  #ifdef HAVE_IPV6
1983 -               s = inet_ntop(con->dst_addr.plain.sa_family, 
1984 -                             con->dst_addr.plain.sa_family == AF_INET6 ? 
1985 +               s = inet_ntop(con->dst_addr.plain.sa_family,
1986 +                             con->dst_addr.plain.sa_family == AF_INET6 ?
1987                               (const void *) &(con->dst_addr.ipv6.sin6_addr) :
1988                               (const void *) &(con->dst_addr.ipv4.sin_addr),
1989                               b2, sizeof(b2)-1);
1990 @@ -828,7 +827,7 @@
1991  #endif
1992                 cgi_env_add(&env, CONST_STR_LEN("REMOTE_ADDR"), s, strlen(s));
1993  
1994 -               ltostr(buf, 
1995 +               ltostr(buf,
1996  #ifdef HAVE_IPV6
1997                         ntohs(con->dst_addr.plain.sa_family == AF_INET6 ? con->dst_addr.ipv6.sin6_port : con->dst_addr.ipv4.sin_port)
1998  #else
1999 @@ -836,19 +835,19 @@
2000  #endif
2001                         );
2002                 cgi_env_add(&env, CONST_STR_LEN("REMOTE_PORT"), buf, strlen(buf));
2003 -               
2004 +
2005                 if (!buffer_is_empty(con->authed_user)) {
2006                         cgi_env_add(&env, CONST_STR_LEN("REMOTE_USER"),
2007                                     CONST_BUF_LEN(con->authed_user));
2008                 }
2009 -               
2010 +
2011                 /* request.content_length < SSIZE_MAX, see request.c */
2012                 ltostr(buf, con->request.content_length);
2013                 cgi_env_add(&env, CONST_STR_LEN("CONTENT_LENGTH"), buf, strlen(buf));
2014                 cgi_env_add(&env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(con->physical.path));
2015                 cgi_env_add(&env, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path));
2016                 cgi_env_add(&env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(con->physical.doc_root));
2017 -               
2018 +
2019                 /* for valgrind */
2020                 if (NULL != (s = getenv("LD_PRELOAD"))) {
2021                         cgi_env_add(&env, CONST_STR_LEN("LD_PRELOAD"), s, strlen(s));
2022 @@ -863,24 +862,24 @@
2023                         cgi_env_add(&env, CONST_STR_LEN("SYSTEMROOT"), s, strlen(s));
2024                 }
2025  #endif
2026 -               
2027 +
2028                 for (n = 0; n < con->request.headers->used; n++) {
2029                         data_string *ds;
2030 -                       
2031 +
2032                         ds = (data_string *)con->request.headers->data[n];
2033 -                       
2034 +
2035                         if (ds->value->used && ds->key->used) {
2036                                 size_t j;
2037 -                               
2038 +
2039                                 buffer_reset(p->tmp_buf);
2040 -                               
2041 +
2042                                 if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) {
2043                                         buffer_copy_string(p->tmp_buf, "HTTP_");
2044                                         p->tmp_buf->used--; /* strip \0 after HTTP_ */
2045                                 }
2046 -                               
2047 +
2048                                 buffer_prepare_append(p->tmp_buf, ds->key->used + 2);
2049 -                               
2050 +
2051                                 for (j = 0; j < ds->key->used - 1; j++) {
2052                                         char cr = '_';
2053                                         if (light_isalpha(ds->key->ptr[j])) {
2054 @@ -893,46 +892,46 @@
2055                                         p->tmp_buf->ptr[p->tmp_buf->used++] = cr;
2056                                 }
2057                                 p->tmp_buf->ptr[p->tmp_buf->used++] = '\0';
2058 -                               
2059 +
2060                                 cgi_env_add(&env, CONST_BUF_LEN(p->tmp_buf), CONST_BUF_LEN(ds->value));
2061                         }
2062                 }
2063 -               
2064 +
2065                 for (n = 0; n < con->environment->used; n++) {
2066                         data_string *ds;
2067 -                       
2068 +
2069                         ds = (data_string *)con->environment->data[n];
2070 -                       
2071 +
2072                         if (ds->value->used && ds->key->used) {
2073                                 size_t j;
2074 -                               
2075 +
2076                                 buffer_reset(p->tmp_buf);
2077 -                               
2078 +
2079                                 buffer_prepare_append(p->tmp_buf, ds->key->used + 2);
2080 -                               
2081 +
2082                                 for (j = 0; j < ds->key->used - 1; j++) {
2083 -                                       p->tmp_buf->ptr[p->tmp_buf->used++] = 
2084 -                                               isalpha((unsigned char)ds->key->ptr[j]) ? 
2085 +                                       p->tmp_buf->ptr[p->tmp_buf->used++] =
2086 +                                               isalpha((unsigned char)ds->key->ptr[j]) ?
2087                                                 toupper((unsigned char)ds->key->ptr[j]) : '_';
2088                                 }
2089                                 p->tmp_buf->ptr[p->tmp_buf->used++] = '\0';
2090 -                               
2091 +
2092                                 cgi_env_add(&env, CONST_BUF_LEN(p->tmp_buf), CONST_BUF_LEN(ds->value));
2093                         }
2094                 }
2095 -               
2096 +
2097                 if (env.size == env.used) {
2098                         env.size += 16;
2099                         env.ptr = realloc(env.ptr, env.size * sizeof(*env.ptr));
2100                 }
2101 -               
2102 +
2103                 env.ptr[env.used] = NULL;
2104 -               
2105 +
2106                 /* set up args */
2107                 argc = 3;
2108                 args = malloc(sizeof(*args) * argc);
2109                 i = 0;
2110 -               
2111 +
2112                 if (cgi_handler->used > 1) {
2113                         args[i++] = cgi_handler->ptr;
2114                 }
2115 @@ -942,7 +941,7 @@
2116                 /* search for the last / */
2117                 if (NULL != (c = strrchr(con->physical.path->ptr, '/'))) {
2118                         *c = '\0';
2119 -                       
2120 +
2121                         /* change to the physical directory */
2122                         if (-1 == chdir(con->physical.path->ptr)) {
2123                                 log_error_write(srv, __FILE__, __LINE__, "ssb", "chdir failed:", strerror(errno), con->physical.path);
2124 @@ -954,12 +953,12 @@
2125                 for (i = 3; i < 256; i++) {
2126                         if (i != srv->errorlog_fd) close(i);
2127                 }
2128 -               
2129 +
2130                 /* exec the cgi */
2131                 execve(args[0], args, env.ptr);
2132 -               
2133 +
2134                 log_error_write(srv, __FILE__, __LINE__, "sss", "CGI failed:", strerror(errno), args[0]);
2135 -               
2136 +
2137                 /* */
2138                 SEGFAULT();
2139                 break;
2140 @@ -974,11 +973,11 @@
2141  
2142                 close(from_cgi_fds[1]);
2143                 close(to_cgi_fds[0]);
2144 -               
2145 +
2146                 if (con->request.content_length) {
2147                         chunkqueue *cq = con->request_content_queue;
2148                         chunk *c;
2149 -               
2150 +
2151                         assert(chunkqueue_length(cq) == (off_t)con->request.content_length);
2152  
2153                         /* there is content to send */
2154 @@ -993,16 +992,16 @@
2155                                                 if (-1 == c->file.fd &&  /* open the file if not already open */
2156                                                     -1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) {
2157                                                         log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
2158 -                                       
2159 +
2160                                                         close(from_cgi_fds[0]);
2161                                                         close(to_cgi_fds[1]);
2162                                                         return -1;
2163                                                 }
2164  
2165                                                 c->file.mmap.length = c->file.length;
2166 -                               
2167 +
2168                                                 if (MAP_FAILED == (c->file.mmap.start = mmap(0,  c->file.mmap.length, PROT_READ, MAP_SHARED, c->file.fd, 0))) {
2169 -                                                       log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed: ", 
2170 +                                                       log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed: ",
2171                                                                         strerror(errno), c->file.name,  c->file.fd);
2172  
2173                                                         close(from_cgi_fds[0]);
2174 @@ -1012,7 +1011,7 @@
2175  
2176                                                 close(c->file.fd);
2177                                                 c->file.fd = -1;
2178 -       
2179 +
2180                                                 /* chunk_reset() or chunk_free() will cleanup for us */
2181                                         }
2182  
2183 @@ -1020,7 +1019,7 @@
2184                                                 switch(errno) {
2185                                                 case ENOSPC:
2186                                                         con->http_status = 507;
2187 -               
2188 +
2189                                                         break;
2190                                                 default:
2191                                                         con->http_status = 403;
2192 @@ -1033,7 +1032,7 @@
2193                                                 switch(errno) {
2194                                                 case ENOSPC:
2195                                                         con->http_status = 507;
2196 -               
2197 +
2198                                                         break;
2199                                                 default:
2200                                                         con->http_status = 403;
2201 @@ -1056,103 +1055,100 @@
2202                 }
2203  
2204                 close(to_cgi_fds[1]);
2205 -                               
2206 +
2207                 /* register PID and wait for them asyncronously */
2208                 con->mode = p->id;
2209                 buffer_reset(con->physical.path);
2210 -               
2211 +
2212                 hctx = cgi_handler_ctx_init();
2213 -               
2214 +
2215                 hctx->remote_conn = con;
2216                 hctx->plugin_data = p;
2217                 hctx->pid = pid;
2218                 hctx->fd = from_cgi_fds[0];
2219                 hctx->fde_ndx = -1;
2220 -               
2221 +
2222                 con->plugin_ctx[p->id] = hctx;
2223 -               
2224 +
2225                 fdevent_register(srv->ev, hctx->fd, cgi_handle_fdevent, hctx);
2226                 fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
2227 -               
2228 +
2229                 if (-1 == fdevent_fcntl_set(srv->ev, hctx->fd)) {
2230                         log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed: ", strerror(errno));
2231 -                       
2232 +
2233                         fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
2234                         fdevent_unregister(srv->ev, hctx->fd);
2235 -                       
2236 +
2237                         log_error_write(srv, __FILE__, __LINE__, "sd", "cgi close:", hctx->fd);
2238 -                       
2239 +
2240                         close(hctx->fd);
2241 -                       
2242 +
2243                         cgi_handler_ctx_free(hctx);
2244 -                       
2245 +
2246                         con->plugin_ctx[p->id] = NULL;
2247 -                       
2248 +
2249                         return -1;
2250                 }
2251 -               
2252 +
2253                 break;
2254         }
2255         }
2256 -       
2257 +
2258         return 0;
2259  #else
2260         return -1;
2261  #endif
2262  }
2263  
2264 -#define PATCH(x) \
2265 -       p->conf.x = s->x;
2266  static int mod_cgi_patch_connection(server *srv, connection *con, plugin_data *p) {
2267         size_t i, j;
2268         plugin_config *s = p->config_storage[0];
2269 -       
2270 -       PATCH(cgi);
2271 -       
2272 +
2273 +       PATCH_OPTION(cgi);
2274 +
2275         /* skip the first, the global context */
2276         for (i = 1; i < srv->config_context->used; i++) {
2277                 data_config *dc = (data_config *)srv->config_context->data[i];
2278                 s = p->config_storage[i];
2279 -               
2280 +
2281                 /* condition didn't match */
2282                 if (!config_check_cond(srv, con, dc)) continue;
2283 -               
2284 +
2285                 /* merge config */
2286                 for (j = 0; j < dc->value->used; j++) {
2287                         data_unset *du = dc->value->data[j];
2288 -                       
2289 +
2290                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("cgi.assign"))) {
2291 -                               PATCH(cgi);
2292 +                               PATCH_OPTION(cgi);
2293                         }
2294                 }
2295         }
2296 -       
2297 +
2298         return 0;
2299  }
2300 -#undef PATCH
2301  
2302  URIHANDLER_FUNC(cgi_is_handled) {
2303         size_t k, s_len;
2304         plugin_data *p = p_d;
2305         buffer *fn = con->physical.path;
2306 -       
2307 +
2308         if (fn->used == 0) return HANDLER_GO_ON;
2309 -       
2310 +
2311         mod_cgi_patch_connection(srv, con, p);
2312 -       
2313 +
2314         s_len = fn->used - 1;
2315 -       
2316 +
2317         for (k = 0; k < p->conf.cgi->used; k++) {
2318                 data_string *ds = (data_string *)p->conf.cgi->data[k];
2319                 size_t ct_len = ds->key->used - 1;
2320 -               
2321 +
2322                 if (ds->key->used == 0) continue;
2323                 if (s_len < ct_len) continue;
2324 -               
2325 +
2326                 if (0 == strncmp(fn->ptr + s_len - ct_len, ds->key->ptr, ct_len)) {
2327                         if (cgi_create_env(srv, con, p, ds->value)) {
2328                                 con->http_status = 500;
2329 -                               
2330 +
2331                                 buffer_reset(con->physical.path);
2332                                 return HANDLER_FINISHED;
2333                         }
2334 @@ -1160,7 +1156,7 @@
2335                         break;
2336                 }
2337         }
2338 -       
2339 +
2340         return HANDLER_GO_ON;
2341  }
2342  
2343 @@ -1168,11 +1164,11 @@
2344         plugin_data *p = p_d;
2345         size_t ndx;
2346         /* the trigger handle only cares about lonely PID which we have to wait for */
2347 -#ifndef __WIN32
2348 +#ifndef _WIN32
2349  
2350         for (ndx = 0; ndx < p->cgi_pid.used; ndx++) {
2351                 int status;
2352 -               
2353 +
2354                 switch(waitpid(p->cgi_pid.ptr[ndx], &status, WNOHANG)) {
2355                 case 0:
2356                         /* not finished yet */
2357 @@ -1182,7 +1178,7 @@
2358                         break;
2359                 case -1:
2360                         log_error_write(srv, __FILE__, __LINE__, "ss", "waitpid failed: ", strerror(errno));
2361 -                       
2362 +
2363                         return HANDLER_ERROR;
2364                 default:
2365  
2366 @@ -1193,16 +1189,16 @@
2367                         } else {
2368                                 log_error_write(srv, __FILE__, __LINE__, "s", "cgi died ?");
2369                         }
2370 -                       
2371 +
2372                         cgi_pid_del(srv, p, p->cgi_pid.ptr[ndx]);
2373 -                       /* del modified the buffer structure 
2374 +                       /* del modified the buffer structure
2375                          * and copies the last entry to the current one
2376                          * -> recheck the current index
2377                          */
2378                         ndx--;
2379                 }
2380         }
2381 -#endif 
2382 +#endif
2383         return HANDLER_GO_ON;
2384  }
2385  
2386 @@ -1210,15 +1206,15 @@
2387         int status;
2388         plugin_data *p = p_d;
2389         handler_ctx *hctx = con->plugin_ctx[p->id];
2390 -       
2391 +
2392         if (con->mode != p->id) return HANDLER_GO_ON;
2393         if (NULL == hctx) return HANDLER_GO_ON;
2394 -       
2395 +
2396  #if 0
2397         log_error_write(srv, __FILE__, __LINE__, "sdd", "subrequest, pid =", hctx, hctx->pid);
2398 -#endif 
2399 +#endif
2400         if (hctx->pid == 0) return HANDLER_FINISHED;
2401 -#ifndef __WIN32        
2402 +#ifndef _WIN32
2403         switch(waitpid(hctx->pid, &status, WNOHANG)) {
2404         case 0:
2405                 /* we only have for events here if we don't have the header yet,
2406 @@ -1228,61 +1224,61 @@
2407                 return HANDLER_WAIT_FOR_EVENT;
2408         case -1:
2409                 if (errno == EINTR) return HANDLER_WAIT_FOR_EVENT;
2410 -               
2411 +
2412                 if (errno == ECHILD && con->file_started == 0) {
2413                         /*
2414 -                        * second round but still not response 
2415 +                        * second round but still not response
2416                          */
2417 -                       return HANDLER_WAIT_FOR_EVENT; 
2418 +                       return HANDLER_WAIT_FOR_EVENT;
2419                 }
2420 -               
2421 +
2422                 log_error_write(srv, __FILE__, __LINE__, "ss", "waitpid failed: ", strerror(errno));
2423                 con->mode = DIRECT;
2424                 con->http_status = 500;
2425 -               
2426 +
2427                 hctx->pid = 0;
2428 -               
2429 +
2430                 fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
2431                 fdevent_unregister(srv->ev, hctx->fd);
2432 -               
2433 +
2434                 if (close(hctx->fd)) {
2435                         log_error_write(srv, __FILE__, __LINE__, "sds", "cgi close failed ", hctx->fd, strerror(errno));
2436                 }
2437 -               
2438 +
2439                 cgi_handler_ctx_free(hctx);
2440 -               
2441 +
2442                 con->plugin_ctx[p->id] = NULL;
2443 -               
2444 +
2445                 return HANDLER_FINISHED;
2446         default:
2447 -               /* cgi process exited cleanly 
2448 -                * 
2449 -                * check if we already got the response 
2450 +               /* cgi process exited cleanly
2451 +                *
2452 +                * check if we already got the response
2453                  */
2454 -               
2455 +
2456                 if (!con->file_started) return HANDLER_WAIT_FOR_EVENT;
2457 -               
2458 +
2459                 if (WIFEXITED(status)) {
2460                         /* nothing */
2461                 } else {
2462                         log_error_write(srv, __FILE__, __LINE__, "s", "cgi died ?");
2463 -                       
2464 +
2465                         con->mode = DIRECT;
2466                         con->http_status = 500;
2467 -                       
2468 +
2469                 }
2470 -               
2471 +
2472                 hctx->pid = 0;
2473 -               
2474 +
2475                 fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
2476                 fdevent_unregister(srv->ev, hctx->fd);
2477 -               
2478 +
2479                 if (close(hctx->fd)) {
2480                         log_error_write(srv, __FILE__, __LINE__, "sds", "cgi close failed ", hctx->fd, strerror(errno));
2481                 }
2482 -               
2483 +
2484                 cgi_handler_ctx_free(hctx);
2485 -               
2486 +
2487                 con->plugin_ctx[p->id] = NULL;
2488                 return HANDLER_FINISHED;
2489         }
2490 @@ -1306,8 +1302,8 @@
2491         p->init           = mod_cgi_init;
2492         p->cleanup        = mod_cgi_free;
2493         p->set_defaults   = mod_fastcgi_set_defaults;
2494 -       
2495 +
2496         p->data        = NULL;
2497 -       
2498 +
2499         return 0;
2500  }
2501
2502 Property changes on: src/mod_cgi.c
2503 ___________________________________________________________________
2504 Name: svn:eol-style
2505    + native
2506
2507 Index: src/network_write.c
2508 ===================================================================
2509 --- src/network_write.c (.../tags/lighttpd-1.4.11)      (revision 1159)
2510 +++ src/network_write.c (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
2511 @@ -1,11 +1,11 @@
2512  #include <sys/types.h>
2513  #include <sys/stat.h>
2514 -#include <sys/time.h>
2515 +
2516  #include <errno.h>
2517  #include <fcntl.h>
2518 -#include <unistd.h>
2519  #include <string.h>
2520  #include <stdlib.h>
2521 +#include <assert.h>
2522  
2523  #include "network.h"
2524  #include "fdevent.h"
2525 @@ -13,9 +13,12 @@
2526  #include "stat_cache.h"
2527  
2528  #include "sys-socket.h"
2529 +#include "sys-files.h"
2530  
2531  #include "network_backends.h"
2532  
2533 +#ifdef USE_WRITE
2534 +
2535  #ifdef HAVE_SYS_FILIO_H
2536  # include <sys/filio.h>
2537  #endif
2538 @@ -24,47 +27,86 @@
2539  #include <sys/resource.h>
2540  #endif
2541  
2542 -int network_write_chunkqueue_write(server *srv, connection *con, int fd, chunkqueue *cq) {
2543 +/**
2544 +* fill the chunkqueue will all the data that we can get
2545 +*
2546 +* this might be optimized into a readv() which uses the chunks
2547 +* as vectors
2548 +*/
2549 +NETWORK_BACKEND_READ(read) {
2550 +    int toread;
2551 +    buffer *b;
2552 +    off_t r;
2553 +
2554 +       /* check how much we have to read */
2555 +       if (ioctl(fd, FIONREAD, &toread)) {
2556 +               log_error_write(srv, __FILE__, __LINE__, "sd",
2557 +                               "ioctl failed: ",
2558 +                               fd);
2559 +               return NETWORK_STATUS_FATAL_ERROR;
2560 +       }
2561 +
2562 +       if (toread == 0) return NETWORK_STATUS_WAIT_FOR_EVENT;
2563 +
2564 +    /*
2565 +    * our chunk queue is quiet large already
2566 +    *
2567 +    * let's buffer it to disk
2568 +    */
2569 +
2570 +    b = chunkqueue_get_append_buffer(cq);
2571 +
2572 +    buffer_prepare_copy(b, toread);
2573 +
2574 +    if (-1 == (r = read(fd, b->ptr, toread))) {
2575 +               log_error_write(srv, __FILE__, __LINE__, "sds",
2576 +                               "unexpected end-of-file (perhaps the proxy process died):",
2577 +                               fd, strerror(errno));
2578 +               return NETWORK_STATUS_FATAL_ERROR;
2579 +       }
2580 +
2581 +       /* this should be catched by the b > 0 above */
2582 +       assert(r);
2583 +       b->used += r + 1;
2584 +       b->ptr[b->used - 1] = '\0';
2585 +
2586 +    return NETWORK_STATUS_SUCCESS;
2587 +}
2588 +
2589 +NETWORK_BACKEND_WRITE(write) {
2590         chunk *c;
2591         size_t chunks_written = 0;
2592 -       
2593 +
2594         for(c = cq->first; c; c = c->next) {
2595                 int chunk_finished = 0;
2596 -               
2597 +
2598                 switch(c->type) {
2599                 case MEM_CHUNK: {
2600                         char * offset;
2601                         size_t toSend;
2602                         ssize_t r;
2603 -                       
2604 +
2605                         if (c->mem->used == 0) {
2606                                 chunk_finished = 1;
2607                                 break;
2608                         }
2609 -                       
2610 +
2611                         offset = c->mem->ptr + c->offset;
2612                         toSend = c->mem->used - 1 - c->offset;
2613 -#ifdef __WIN32 
2614 -                       if ((r = send(fd, offset, toSend, 0)) < 0) {
2615 -                               log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed: ", strerror(errno), fd);
2616 -                               
2617 -                               return -1;
2618 -                       }
2619 -#else
2620 +
2621                         if ((r = write(fd, offset, toSend)) < 0) {
2622                                 log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed: ", strerror(errno), fd);
2623 -                               
2624 -                               return -1;
2625 +
2626 +                               return NETWORK_STATUS_FATAL_ERROR;
2627                         }
2628 -#endif
2629 -                       
2630 +
2631                         c->offset += r;
2632                         cq->bytes_out += r;
2633 -                       
2634 +
2635                         if (c->offset == (off_t)c->mem->used - 1) {
2636                                 chunk_finished = 1;
2637                         }
2638 -                       
2639 +
2640                         break;
2641                 }
2642                 case FILE_CHUNK: {
2643 @@ -76,93 +118,89 @@
2644                         size_t toSend;
2645                         stat_cache_entry *sce = NULL;
2646                         int ifd;
2647 -                       
2648 +
2649                         if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) {
2650                                 log_error_write(srv, __FILE__, __LINE__, "sb",
2651                                                 strerror(errno), c->file.name);
2652 -                               return -1;
2653 +                               return NETWORK_STATUS_FATAL_ERROR;
2654                         }
2655 -                       
2656 +
2657                         offset = c->file.start + c->offset;
2658                         toSend = c->file.length - c->offset;
2659 -                       
2660 +
2661                         if (offset > sce->st.st_size) {
2662                                 log_error_write(srv, __FILE__, __LINE__, "sb", "file was shrinked:", c->file.name);
2663 -                               
2664 -                               return -1;
2665 +
2666 +                               return NETWORK_STATUS_FATAL_ERROR;
2667                         }
2668  
2669                         if (-1 == (ifd = open(c->file.name->ptr, O_RDONLY))) {
2670                                 log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
2671 -                               
2672 -                               return -1;
2673 +
2674 +                               return NETWORK_STATUS_FATAL_ERROR;
2675                         }
2676 -                       
2677 +
2678  #if defined USE_MMAP
2679                         if (MAP_FAILED == (p = mmap(0, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0))) {
2680                                 log_error_write(srv, __FILE__, __LINE__, "ss", "mmap failed: ", strerror(errno));
2681  
2682                                 close(ifd);
2683 -                               
2684 -                               return -1;
2685 +
2686 +                               return NETWORK_STATUS_FATAL_ERROR;
2687                         }
2688                         close(ifd);
2689  
2690                         if ((r = write(fd, p + offset, toSend)) <= 0) {
2691                                 log_error_write(srv, __FILE__, __LINE__, "ss", "write failed: ", strerror(errno));
2692                                 munmap(p, sce->st.st_size);
2693 -                               return -1;
2694 +                               return NETWORK_STATUS_FATAL_ERROR;
2695                         }
2696 -                       
2697 +
2698                         munmap(p, sce->st.st_size);
2699  #else
2700                         buffer_prepare_copy(srv->tmp_buf, toSend);
2701 -                       
2702 +
2703                         lseek(ifd, offset, SEEK_SET);
2704                         if (-1 == (toSend = read(ifd, srv->tmp_buf->ptr, toSend))) {
2705                                 log_error_write(srv, __FILE__, __LINE__, "ss", "read: ", strerror(errno));
2706                                 close(ifd);
2707 -                               
2708 -                               return -1;
2709 +
2710 +                               return NETWORK_STATUS_FATAL_ERROR;
2711                         }
2712                         close(ifd);
2713  
2714                         if (-1 == (r = send(fd, srv->tmp_buf->ptr, toSend, 0))) {
2715                                 log_error_write(srv, __FILE__, __LINE__, "ss", "write: ", strerror(errno));
2716 -                               
2717 -                               return -1;
2718 +
2719 +                               return NETWORK_STATUS_FATAL_ERROR;
2720                         }
2721  #endif
2722                         c->offset += r;
2723                         cq->bytes_out += r;
2724 -                       
2725 +
2726                         if (c->offset == c->file.length) {
2727                                 chunk_finished = 1;
2728                         }
2729 -                       
2730 +
2731                         break;
2732                 }
2733                 default:
2734 -                       
2735 +
2736                         log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
2737 -                       
2738 -                       return -1;
2739 +
2740 +                       return NETWORK_STATUS_FATAL_ERROR;
2741                 }
2742 -               
2743 +
2744                 if (!chunk_finished) {
2745                         /* not finished yet */
2746 -                       
2747 +
2748                         break;
2749                 }
2750 -               
2751 +
2752                 chunks_written++;
2753         }
2754  
2755 -       return chunks_written;
2756 +       return NETWORK_STATUS_SUCCESS;
2757  }
2758  
2759 -#if 0
2760 -network_write_init(void) {
2761 -       p->write = network_write_write_chunkset;
2762 -}
2763  #endif
2764
2765 Property changes on: src/network_write.c
2766 ___________________________________________________________________
2767 Name: svn:eol-style
2768    + native
2769
2770 Index: src/joblist.c
2771 ===================================================================
2772 --- src/joblist.c       (.../tags/lighttpd-1.4.11)      (revision 1159)
2773 +++ src/joblist.c       (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
2774 @@ -7,7 +7,7 @@
2775  
2776  int joblist_append(server *srv, connection *con) {
2777         if (con->in_joblist) return 0;
2778 -       
2779 +
2780         if (srv->joblist->size == 0) {
2781                 srv->joblist->size  = 16;
2782                 srv->joblist->ptr   = malloc(sizeof(*srv->joblist->ptr) * srv->joblist->size);
2783 @@ -15,15 +15,15 @@
2784                 srv->joblist->size += 16;
2785                 srv->joblist->ptr   = realloc(srv->joblist->ptr, sizeof(*srv->joblist->ptr) * srv->joblist->size);
2786         }
2787 -       
2788 +
2789         srv->joblist->ptr[srv->joblist->used++] = con;
2790 -       
2791 +
2792         return 0;
2793  }
2794  
2795  void joblist_free(server *srv, connections *joblist) {
2796         UNUSED(srv);
2797 -               
2798 +
2799         free(joblist->ptr);
2800         free(joblist);
2801  }
2802 @@ -31,14 +31,14 @@
2803  connection *fdwaitqueue_unshift(server *srv, connections *fdwaitqueue) {
2804         connection *con;
2805         UNUSED(srv);
2806 -               
2807 -       
2808 +
2809 +
2810         if (fdwaitqueue->used == 0) return NULL;
2811 -       
2812 +
2813         con = fdwaitqueue->ptr[0];
2814 -       
2815 +
2816         memmove(fdwaitqueue->ptr, &(fdwaitqueue->ptr[1]), --fdwaitqueue->used * sizeof(*(fdwaitqueue->ptr)));
2817 -       
2818 +
2819         return con;
2820  }
2821  
2822 @@ -50,9 +50,9 @@
2823                 srv->fdwaitqueue->size += 16;
2824                 srv->fdwaitqueue->ptr   = realloc(srv->fdwaitqueue->ptr, sizeof(*(srv->fdwaitqueue->ptr)) * srv->fdwaitqueue->size);
2825         }
2826 -       
2827 +
2828         srv->fdwaitqueue->ptr[srv->fdwaitqueue->used++] = con;
2829 -       
2830 +
2831         return 0;
2832  }
2833  
2834
2835 Property changes on: src/joblist.c
2836 ___________________________________________________________________
2837 Name: svn:eol-style
2838    + native
2839
2840 Index: src/mod_cml.c
2841 ===================================================================
2842 --- src/mod_cml.c       (.../tags/lighttpd-1.4.11)      (revision 1159)
2843 +++ src/mod_cml.c       (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
2844 @@ -4,7 +4,6 @@
2845  #include <stdlib.h>
2846  #include <string.h>
2847  #include <errno.h>
2848 -#include <unistd.h>
2849  #include <stdio.h>
2850  
2851  #include "buffer.h"
2852 @@ -20,50 +19,50 @@
2853  /* init the plugin data */
2854  INIT_FUNC(mod_cml_init) {
2855         plugin_data *p;
2856 -       
2857 +
2858         p = calloc(1, sizeof(*p));
2859 -       
2860 +
2861         p->basedir         = buffer_init();
2862         p->baseurl         = buffer_init();
2863         p->trigger_handler = buffer_init();
2864 -       
2865 +
2866         return p;
2867  }
2868  
2869  /* detroy the plugin data */
2870  FREE_FUNC(mod_cml_free) {
2871         plugin_data *p = p_d;
2872 -       
2873 +
2874         UNUSED(srv);
2875  
2876         if (!p) return HANDLER_GO_ON;
2877 -       
2878 +
2879         if (p->config_storage) {
2880                 size_t i;
2881                 for (i = 0; i < srv->config_context->used; i++) {
2882                         plugin_config *s = p->config_storage[i];
2883 -                       
2884 +
2885                         buffer_free(s->ext);
2886 -                       
2887 +
2888                         buffer_free(s->mc_namespace);
2889                         buffer_free(s->power_magnet);
2890                         array_free(s->mc_hosts);
2891 -                       
2892 +
2893  #if defined(HAVE_MEMCACHE_H)
2894                         if (s->mc) mc_free(s->mc);
2895  #endif
2896 -                       
2897 +
2898                         free(s);
2899                 }
2900                 free(p->config_storage);
2901         }
2902 -       
2903 +
2904         buffer_free(p->trigger_handler);
2905         buffer_free(p->basedir);
2906         buffer_free(p->baseurl);
2907 -       
2908 +
2909         free(p);
2910 -       
2911 +
2912         return HANDLER_GO_ON;
2913  }
2914  
2915 @@ -72,22 +71,22 @@
2916  SETDEFAULTS_FUNC(mod_cml_set_defaults) {
2917         plugin_data *p = p_d;
2918         size_t i = 0;
2919 -       
2920 -       config_values_t cv[] = { 
2921 +
2922 +       config_values_t cv[] = {
2923                 { "cml.extension",              NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
2924                 { "cml.memcache-hosts",         NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },        /* 1 */
2925                 { "cml.memcache-namespace",     NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 2 */
2926                 { "cml.power-magnet",           NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 3 */
2927                 { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
2928         };
2929 -       
2930 +
2931         if (!p) return HANDLER_ERROR;
2932 -       
2933 +
2934         p->config_storage = malloc(srv->config_context->used * sizeof(specific_config *));
2935 -       
2936 +
2937         for (i = 0; i < srv->config_context->used; i++) {
2938                 plugin_config *s;
2939 -               
2940 +
2941                 s = malloc(sizeof(plugin_config));
2942                 s->ext    = buffer_init();
2943                 s->mc_hosts       = array_init();
2944 @@ -96,87 +95,84 @@
2945  #if defined(HAVE_MEMCACHE_H)
2946                 s->mc = NULL;
2947  #endif
2948 -               
2949 +
2950                 cv[0].destination = s->ext;
2951                 cv[1].destination = s->mc_hosts;
2952                 cv[2].destination = s->mc_namespace;
2953                 cv[3].destination = s->power_magnet;
2954 -               
2955 +
2956                 p->config_storage[i] = s;
2957 -       
2958 +
2959                 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
2960                         return HANDLER_ERROR;
2961                 }
2962 -               
2963 +
2964                 if (s->mc_hosts->used) {
2965  #if defined(HAVE_MEMCACHE_H)
2966                         size_t k;
2967                         s->mc = mc_new();
2968 -               
2969 +
2970                         for (k = 0; k < s->mc_hosts->used; k++) {
2971                                 data_string *ds = (data_string *)s->mc_hosts->data[k];
2972 -                               
2973 +
2974                                 if (0 != mc_server_add4(s->mc, ds->value->ptr)) {
2975 -                                       log_error_write(srv, __FILE__, __LINE__, "sb", 
2976 -                                                       "connection to host failed:", 
2977 +                                       log_error_write(srv, __FILE__, __LINE__, "sb",
2978 +                                                       "connection to host failed:",
2979                                                         ds->value);
2980 -                                       
2981 +
2982                                         return HANDLER_ERROR;
2983                                 }
2984                         }
2985  #else
2986 -                       log_error_write(srv, __FILE__, __LINE__, "s", 
2987 +                       log_error_write(srv, __FILE__, __LINE__, "s",
2988                                         "memcache support is not compiled in but cml.memcache-hosts is set, aborting");
2989                         return HANDLER_ERROR;
2990  #endif
2991                 }
2992         }
2993 -       
2994 +
2995         return HANDLER_GO_ON;
2996  }
2997  
2998 -#define PATCH(x) \
2999 -       p->conf.x = s->x;
3000  static int mod_cml_patch_connection(server *srv, connection *con, plugin_data *p) {
3001         size_t i, j;
3002         plugin_config *s = p->config_storage[0];
3003 -       
3004 -       PATCH(ext);
3005 +
3006 +       PATCH_OPTION(ext);
3007  #if defined(HAVE_MEMCACHE_H)
3008 -       PATCH(mc);
3009 +       PATCH_OPTION(mc);
3010  #endif
3011 -       PATCH(mc_namespace);
3012 -       PATCH(power_magnet);
3013 -       
3014 +       PATCH_OPTION(mc_namespace);
3015 +       PATCH_OPTION(power_magnet);
3016 +
3017         /* skip the first, the global context */
3018         for (i = 1; i < srv->config_context->used; i++) {
3019                 data_config *dc = (data_config *)srv->config_context->data[i];
3020                 s = p->config_storage[i];
3021 -               
3022 +
3023                 /* condition didn't match */
3024                 if (!config_check_cond(srv, con, dc)) continue;
3025 -               
3026 +
3027                 /* merge config */
3028                 for (j = 0; j < dc->value->used; j++) {
3029                         data_unset *du = dc->value->data[j];
3030 -                       
3031 +
3032                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("cml.extension"))) {
3033 -                               PATCH(ext);
3034 +                               PATCH_OPTION(ext);
3035                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("cml.memcache-hosts"))) {
3036  #if defined(HAVE_MEMCACHE_H)
3037 -                               PATCH(mc);
3038 +                               PATCH_OPTION(mc);
3039  #endif
3040                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("cml.memcache-namespace"))) {
3041 -                               PATCH(mc_namespace);
3042 +                               PATCH_OPTION(mc_namespace);
3043                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("cml.power-magnet"))) {
3044 -                               PATCH(power_magnet);
3045 +                               PATCH_OPTION(power_magnet);
3046                         }
3047                 }
3048         }
3049 -       
3050 +
3051         return 0;
3052  }
3053 -#undef PATCH
3054  
3055  int cache_call_lua(server *srv, connection *con, plugin_data *p, buffer *cml_file) {
3056         buffer *b;
3057 @@ -187,57 +183,57 @@
3058         b = p->baseurl;
3059         buffer_copy_string_buffer(b, con->uri.path);
3060         for (c = b->ptr + b->used - 1; c > b->ptr && *c != '/'; c--);
3061 -       
3062 +
3063         if (*c == '/') {
3064                 b->used = c - b->ptr + 2;
3065                 *(c+1) = '\0';
3066         }
3067 -       
3068 +
3069         b = p->basedir;
3070         buffer_copy_string_buffer(b, con->physical.path);
3071         for (c = b->ptr + b->used - 1; c > b->ptr && *c != '/'; c--);
3072 -       
3073 +
3074         if (*c == '/') {
3075                 b->used = c - b->ptr + 2;
3076                 *(c+1) = '\0';
3077         }
3078 -       
3079  
3080 +
3081         /* prepare variables
3082          *   - cookie-based
3083          *   - get-param-based
3084          */
3085 -       
3086 +
3087         return cache_parse_lua(srv, con, p, cml_file);
3088 -       
3089 +
3090  }
3091  
3092  URIHANDLER_FUNC(mod_cml_power_magnet) {
3093         plugin_data *p = p_d;
3094 -       
3095 +
3096         mod_cml_patch_connection(srv, con, p);
3097 -       
3098 +
3099         buffer_reset(p->basedir);
3100         buffer_reset(p->baseurl);
3101         buffer_reset(p->trigger_handler);
3102  
3103         if (buffer_is_empty(p->conf.power_magnet)) return HANDLER_GO_ON;
3104 -       
3105 -       /* 
3106 +
3107 +       /*
3108          * power-magnet:
3109          * cml.power-magnet = server.docroot + "/rewrite.cml"
3110          *
3111          * is called on EACH request, take the original REQUEST_URI and modifies the
3112 -        * request header as neccesary. 
3113 +        * request header as neccesary.
3114          *
3115          * First use:
3116          * if file_exists("/maintainance.html") {
3117          *   output_include = ( "/maintainance.html" )
3118 -        *   return CACHE_HIT 
3119 +        *   return CACHE_HIT
3120          * }
3121          *
3122          * as we only want to rewrite HTML like requests we should cover it in a conditional
3123 -        * 
3124 +        *
3125          * */
3126  
3127         switch(cache_call_lua(srv, con, p, p->conf.power_magnet)) {
3128 @@ -266,20 +262,20 @@
3129  
3130  URIHANDLER_FUNC(mod_cml_is_handled) {
3131         plugin_data *p = p_d;
3132 -       
3133 +
3134         if (buffer_is_empty(con->physical.path)) return HANDLER_ERROR;
3135 -       
3136 +
3137         mod_cml_patch_connection(srv, con, p);
3138 -       
3139 +
3140         buffer_reset(p->basedir);
3141         buffer_reset(p->baseurl);
3142         buffer_reset(p->trigger_handler);
3143  
3144         if (buffer_is_empty(p->conf.ext)) return HANDLER_GO_ON;
3145 -       
3146 +
3147         if (!buffer_is_equal_right_len(con->physical.path, p->conf.ext, p->conf.ext->used - 1)) {
3148                 return HANDLER_GO_ON;
3149 -       } 
3150 +       }
3151  
3152         switch(cache_call_lua(srv, con, p, con->physical.path)) {
3153         case -1:
3154 @@ -311,15 +307,15 @@
3155  int mod_cml_plugin_init(plugin *p) {
3156         p->version     = LIGHTTPD_VERSION_ID;
3157         p->name        = buffer_init_string("cache");
3158 -       
3159 +
3160         p->init        = mod_cml_init;
3161         p->cleanup     = mod_cml_free;
3162         p->set_defaults  = mod_cml_set_defaults;
3163 -       
3164 +
3165         p->handle_subrequest_start = mod_cml_is_handled;
3166         p->handle_physical         = mod_cml_power_magnet;
3167 -       
3168 +
3169         p->data        = NULL;
3170 -       
3171 +
3172         return 0;
3173  }
3174
3175 Property changes on: src/mod_cml.c
3176 ___________________________________________________________________
3177 Name: svn:eol-style
3178    + native
3179
3180
3181 Property changes on: src/joblist.h
3182 ___________________________________________________________________
3183 Name: svn:eol-style
3184    + native
3185
3186 Index: src/mod_secure_download.c
3187 ===================================================================
3188 --- src/mod_secure_download.c   (.../tags/lighttpd-1.4.11)      (revision 1159)
3189 +++ src/mod_secure_download.c   (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
3190 @@ -25,7 +25,7 @@
3191  #ifdef USE_OPENSSL
3192  #define IN const
3193  #else
3194 -#define IN 
3195 +#define IN
3196  #endif
3197  #define OUT
3198  
3199 @@ -36,28 +36,28 @@
3200         buffer *doc_root;
3201         buffer *secret;
3202         buffer *uri_prefix;
3203 -       
3204 +
3205         unsigned short timeout;
3206  } plugin_config;
3207  
3208  typedef struct {
3209         PLUGIN_DATA;
3210 -       
3211 +
3212         buffer *md5;
3213 -       
3214 +
3215         plugin_config **config_storage;
3216 -       
3217 -       plugin_config conf; 
3218 +
3219 +       plugin_config conf;
3220  } plugin_data;
3221  
3222  /* init the plugin data */
3223  INIT_FUNC(mod_secdownload_init) {
3224         plugin_data *p;
3225 -       
3226 +
3227         p = calloc(1, sizeof(*p));
3228 -       
3229 +
3230         p->md5 = buffer_init();
3231 -       
3232 +
3233         return p;
3234  }
3235  
3236 @@ -65,27 +65,27 @@
3237  FREE_FUNC(mod_secdownload_free) {
3238         plugin_data *p = p_d;
3239         UNUSED(srv);
3240 -       
3241 +
3242         if (!p) return HANDLER_GO_ON;
3243 -       
3244 +
3245         if (p->config_storage) {
3246                 size_t i;
3247                 for (i = 0; i < srv->config_context->used; i++) {
3248                         plugin_config *s = p->config_storage[i];
3249 -                       
3250 +
3251                         buffer_free(s->secret);
3252                         buffer_free(s->doc_root);
3253                         buffer_free(s->uri_prefix);
3254 -                       
3255 +
3256                         free(s);
3257                 }
3258                 free(p->config_storage);
3259         }
3260 -       
3261 +
3262         buffer_free(p->md5);
3263 -       
3264 +
3265         free(p);
3266 -       
3267 +
3268         return HANDLER_GO_ON;
3269  }
3270  
3271 @@ -94,108 +94,104 @@
3272  SETDEFAULTS_FUNC(mod_secdownload_set_defaults) {
3273         plugin_data *p = p_d;
3274         size_t i = 0;
3275 -       
3276 -       config_values_t cv[] = { 
3277 +
3278 +       config_values_t cv[] = {
3279                 { "secdownload.secret",            NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
3280                 { "secdownload.document-root",     NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
3281                 { "secdownload.uri-prefix",        NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 2 */
3282                 { "secdownload.timeout",           NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 3 */
3283                 { NULL,                            NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
3284         };
3285 -       
3286 +
3287         if (!p) return HANDLER_ERROR;
3288 -       
3289 +
3290         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
3291 -       
3292 +
3293         for (i = 0; i < srv->config_context->used; i++) {
3294                 plugin_config *s;
3295 -               
3296 +
3297                 s = calloc(1, sizeof(plugin_config));
3298                 s->secret        = buffer_init();
3299                 s->doc_root      = buffer_init();
3300                 s->uri_prefix    = buffer_init();
3301                 s->timeout       = 60;
3302 -               
3303 +
3304                 cv[0].destination = s->secret;
3305                 cv[1].destination = s->doc_root;
3306                 cv[2].destination = s->uri_prefix;
3307                 cv[3].destination = &(s->timeout);
3308 -               
3309 +
3310                 p->config_storage[i] = s;
3311 -       
3312 +
3313                 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
3314                         return HANDLER_ERROR;
3315                 }
3316         }
3317 -       
3318 +
3319         return HANDLER_GO_ON;
3320  }
3321  
3322  /**
3323   * checks if the supplied string is a MD5 string
3324 - * 
3325 + *
3326   * @param str a possible MD5 string
3327   * @return if the supplied string is a valid MD5 string 1 is returned otherwise 0
3328   */
3329  
3330  int is_hex_len(const char *str, size_t len) {
3331         size_t i;
3332 -       
3333 +
3334         if (NULL == str) return 0;
3335 -       
3336 +
3337         for (i = 0; i < len && *str; i++, str++) {
3338                 /* illegal characters */
3339                 if (!((*str >= '0' && *str <= '9') ||
3340                       (*str >= 'a' && *str <= 'f') ||
3341 -                     (*str >= 'A' && *str <= 'F')) 
3342 +                     (*str >= 'A' && *str <= 'F'))
3343                     ) {
3344                         return 0;
3345                 }
3346         }
3347 -       
3348 +
3349         return i == len;
3350  }
3351  
3352 -#define PATCH(x) \
3353 -       p->conf.x = s->x;
3354  static int mod_secdownload_patch_connection(server *srv, connection *con, plugin_data *p) {
3355         size_t i, j;
3356         plugin_config *s = p->config_storage[0];
3357 -       
3358 -       PATCH(secret);
3359 -       PATCH(doc_root);
3360 -       PATCH(uri_prefix);
3361 -       PATCH(timeout);
3362 -       
3363 +
3364 +       PATCH_OPTION(secret);
3365 +       PATCH_OPTION(doc_root);
3366 +       PATCH_OPTION(uri_prefix);
3367 +       PATCH_OPTION(timeout);
3368 +
3369         /* skip the first, the global context */
3370         for (i = 1; i < srv->config_context->used; i++) {
3371                 data_config *dc = (data_config *)srv->config_context->data[i];
3372                 s = p->config_storage[i];
3373 -               
3374 +
3375                 /* condition didn't match */
3376                 if (!config_check_cond(srv, con, dc)) continue;
3377 -               
3378 +
3379                 /* merge config */
3380                 for (j = 0; j < dc->value->used; j++) {
3381                         data_unset *du = dc->value->data[j];
3382 -                       
3383 +
3384                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("secdownload.secret"))) {
3385 -                               PATCH(secret);
3386 +                               PATCH_OPTION(secret);
3387                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("secdownload.document-root"))) {
3388 -                               PATCH(doc_root);
3389 +                               PATCH_OPTION(doc_root);
3390                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("secdownload.uri-prefix"))) {
3391 -                               PATCH(uri_prefix);
3392 +                               PATCH_OPTION(uri_prefix);
3393                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("secdownload.timeout"))) {
3394 -                               PATCH(timeout);
3395 +                               PATCH_OPTION(timeout);
3396                         }
3397                 }
3398         }
3399 -       
3400 +
3401         return 0;
3402  }
3403 -#undef PATCH
3404  
3405 -
3406  URIHANDLER_FUNC(mod_secdownload_uri_handler) {
3407         plugin_data *p = p_d;
3408         MD5_CTX Md5Ctx;
3409 @@ -203,88 +199,88 @@
3410         const char *rel_uri, *ts_str, *md5_str;
3411         time_t ts = 0;
3412         size_t i;
3413 -       
3414 +
3415         if (con->uri.path->used == 0) return HANDLER_GO_ON;
3416 -       
3417 +
3418         mod_secdownload_patch_connection(srv, con, p);
3419  
3420         if (buffer_is_empty(p->conf.uri_prefix)) return HANDLER_GO_ON;
3421 -       
3422 +
3423         if (buffer_is_empty(p->conf.secret)) {
3424                 log_error_write(srv, __FILE__, __LINE__, "s",
3425                                 "secdownload.secret has to be set");
3426                 return HANDLER_ERROR;
3427         }
3428 -       
3429 +
3430         if (buffer_is_empty(p->conf.doc_root)) {
3431                 log_error_write(srv, __FILE__, __LINE__, "s",
3432                                 "secdownload.document-root has to be set");
3433                 return HANDLER_ERROR;
3434         }
3435 -       
3436 -       /* 
3437 +
3438 +       /*
3439          *  /<uri-prefix>[a-f0-9]{32}/[a-f0-9]{8}/<rel-path>
3440          */
3441 -       
3442 +
3443         if (0 != strncmp(con->uri.path->ptr, p->conf.uri_prefix->ptr, p->conf.uri_prefix->used - 1)) return HANDLER_GO_ON;
3444 -       
3445 +
3446         md5_str = con->uri.path->ptr + p->conf.uri_prefix->used - 1;
3447 -       
3448 +
3449         if (!is_hex_len(md5_str, 32)) return HANDLER_GO_ON;
3450         if (*(md5_str + 32) != '/') return HANDLER_GO_ON;
3451 -       
3452 +
3453         ts_str = md5_str + 32 + 1;
3454 -       
3455 +
3456         if (!is_hex_len(ts_str, 8)) return HANDLER_GO_ON;
3457         if (*(ts_str + 8) != '/') return HANDLER_GO_ON;
3458 -       
3459 +
3460         for (i = 0; i < 8; i++) {
3461                 ts = (ts << 4) + hex2int(*(ts_str + i));
3462         }
3463 -       
3464 +
3465         /* timed-out */
3466 -       if (srv->cur_ts - ts > p->conf.timeout || 
3467 +       if (srv->cur_ts - ts > p->conf.timeout ||
3468             srv->cur_ts - ts < -p->conf.timeout) {
3469                 con->http_status = 408;
3470 -               
3471 +
3472                 return HANDLER_FINISHED;
3473         }
3474 -       
3475 +
3476         rel_uri = ts_str + 8;
3477 -       
3478 -       /* checking MD5 
3479 -        * 
3480 +
3481 +       /* checking MD5
3482 +        *
3483          * <secret><rel-path><timestamp-hex>
3484          */
3485 -       
3486 +
3487         buffer_copy_string_buffer(p->md5, p->conf.secret);
3488         buffer_append_string(p->md5, rel_uri);
3489         buffer_append_string_len(p->md5, ts_str, 8);
3490 -       
3491 +
3492         MD5_Init(&Md5Ctx);
3493         MD5_Update(&Md5Ctx, (unsigned char *)p->md5->ptr, p->md5->used - 1);
3494         MD5_Final(HA1, &Md5Ctx);
3495 -       
3496 +
3497         buffer_copy_string_hex(p->md5, (char *)HA1, 16);
3498 -       
3499 +
3500         if (0 != strncmp(md5_str, p->md5->ptr, 32)) {
3501                 con->http_status = 403;
3502 -               
3503 -               log_error_write(srv, __FILE__, __LINE__, "sss", 
3504 +
3505 +               log_error_write(srv, __FILE__, __LINE__, "sss",
3506                                 "md5 invalid:",
3507                                 md5_str, p->md5->ptr);
3508 -               
3509 +
3510                 return HANDLER_FINISHED;
3511         }
3512 -       
3513 +
3514         /* starting with the last / we should have relative-path to the docroot
3515          */
3516 -       
3517 +
3518         buffer_copy_string_buffer(con->physical.doc_root, p->conf.doc_root);
3519         buffer_copy_string(con->physical.rel_path, rel_uri);
3520         buffer_copy_string_buffer(con->physical.path, con->physical.doc_root);
3521         buffer_append_string_buffer(con->physical.path, con->physical.rel_path);
3522 -       
3523 +
3524         return HANDLER_GO_ON;
3525  }
3526  
3527 @@ -293,13 +289,13 @@
3528  int mod_secdownload_plugin_init(plugin *p) {
3529         p->version     = LIGHTTPD_VERSION_ID;
3530         p->name        = buffer_init_string("secdownload");
3531 -       
3532 +
3533         p->init        = mod_secdownload_init;
3534         p->handle_physical  = mod_secdownload_uri_handler;
3535         p->set_defaults  = mod_secdownload_set_defaults;
3536         p->cleanup     = mod_secdownload_free;
3537 -       
3538 +
3539         p->data        = NULL;
3540 -       
3541 +
3542         return 0;
3543  }
3544
3545 Property changes on: src/mod_secure_download.c
3546 ___________________________________________________________________
3547 Name: svn:eol-style
3548    + native
3549
3550 Index: src/connections-glue.c
3551 ===================================================================
3552 --- src/connections-glue.c      (.../tags/lighttpd-1.4.11)      (revision 1159)
3553 +++ src/connections-glue.c      (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
3554 @@ -13,7 +13,7 @@
3555         case CON_STATE_REQUEST_END: return "req-end";
3556         case CON_STATE_RESPONSE_START: return "resp-start";
3557         case CON_STATE_RESPONSE_END: return "resp-end";
3558 -       default: return "(unknown)";    
3559 +       default: return "(unknown)";
3560         }
3561  }
3562  
3563 @@ -30,15 +30,15 @@
3564         case CON_STATE_REQUEST_END: return "Q";
3565         case CON_STATE_RESPONSE_START: return "s";
3566         case CON_STATE_RESPONSE_END: return "S";
3567 -       default: return "x";    
3568 +       default: return "x";
3569         }
3570  }
3571  
3572  int connection_set_state(server *srv, connection *con, connection_state_t state) {
3573         UNUSED(srv);
3574 -       
3575 +
3576         con->state = state;
3577 -       
3578 +
3579         return 0;
3580  }
3581  
3582
3583 Property changes on: src/connections-glue.c
3584 ___________________________________________________________________
3585 Name: svn:eol-style
3586    + native
3587
3588 Index: src/array.c
3589 ===================================================================
3590 --- src/array.c (.../tags/lighttpd-1.4.11)      (revision 1159)
3591 +++ src/array.c (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
3592 @@ -11,12 +11,12 @@
3593  
3594  array *array_init(void) {
3595         array *a;
3596 -       
3597 +
3598         a = calloc(1, sizeof(*a));
3599         assert(a);
3600 -       
3601 +
3602         a->next_power_of_2 = 1;
3603 -       
3604 +
3605         return a;
3606  }
3607  
3608 @@ -43,29 +43,29 @@
3609  void array_free(array *a) {
3610         size_t i;
3611         if (!a) return;
3612 -       
3613 +
3614         if (!a->is_weakref) {
3615                 for (i = 0; i < a->size; i++) {
3616                         if (a->data[i]) a->data[i]->free(a->data[i]);
3617                 }
3618         }
3619 -       
3620 +
3621         if (a->data) free(a->data);
3622         if (a->sorted) free(a->sorted);
3623 -       
3624 +
3625         free(a);
3626  }
3627  
3628  void array_reset(array *a) {
3629         size_t i;
3630         if (!a) return;
3631 -       
3632 +
3633         if (!a->is_weakref) {
3634                 for (i = 0; i < a->used; i++) {
3635                         a->data[i]->reset(a->data[i]);
3636                 }
3637         }
3638 -       
3639 +
3640         a->used = 0;
3641  }
3642  
3643 @@ -84,20 +84,20 @@
3644  static int array_get_index(array *a, const char *key, size_t keylen, int *rndx) {
3645         int ndx = -1;
3646         int i, pos = 0;
3647 -       
3648 +
3649         if (key == NULL) return -1;
3650 -       
3651 +
3652         /* try to find the string */
3653         for (i = pos = a->next_power_of_2 / 2; ; i >>= 1) {
3654                 int cmp;
3655 -               
3656 +
3657                 if (pos < 0) {
3658                         pos += i;
3659                 } else if (pos >= (int)a->used) {
3660                         pos -= i;
3661                 } else {
3662                         cmp = buffer_caseless_compare(key, keylen, a->data[a->sorted[pos]]->key->ptr, a->data[a->sorted[pos]]->key->used);
3663 -                       
3664 +
3665                         if (cmp == 0) {
3666                                 /* found */
3667                                 ndx = a->sorted[pos];
3668 @@ -110,46 +110,46 @@
3669                 }
3670                 if (i == 0) break;
3671         }
3672 -       
3673 +
3674         if (rndx) *rndx = pos;
3675 -       
3676 +
3677         return ndx;
3678  }
3679  
3680  data_unset *array_get_element(array *a, const char *key) {
3681         int ndx;
3682 -       
3683 +
3684         if (-1 != (ndx = array_get_index(a, key, strlen(key) + 1, NULL))) {
3685                 /* found, leave here */
3686 -               
3687 +
3688                 return a->data[ndx];
3689 -       } 
3690 -       
3691 +       }
3692 +
3693         return NULL;
3694  }
3695  
3696  data_unset *array_get_unused_element(array *a, data_type_t t) {
3697         data_unset *ds = NULL;
3698 -       
3699 +
3700         UNUSED(t);
3701  
3702         if (a->size == 0) return NULL;
3703 -       
3704 +
3705         if (a->used == a->size) return NULL;
3706  
3707         if (a->data[a->used]) {
3708                 ds = a->data[a->used];
3709 -               
3710 +
3711                 a->data[a->used] = NULL;
3712         }
3713 -       
3714 +
3715         return ds;
3716  }
3717  
3718  /* replace or insert data, return the old one with the same key */
3719  data_unset *array_replace(array *a, data_unset *du) {
3720         int ndx;
3721 -       
3722 +
3723         if (-1 == (ndx = array_get_index(a, du->key->ptr, du->key->used, NULL))) {
3724                 array_insert_unique(a, du);
3725                 return NULL;
3726 @@ -164,13 +164,13 @@
3727         int ndx = -1;
3728         int pos = 0;
3729         size_t j;
3730 -       
3731 -       /* generate unique index if neccesary */
3732 +
3733 +       /* generate unique index if necessary */
3734         if (str->key->used == 0 || str->is_index_key) {
3735                 buffer_copy_long(str->key, a->unique_ndx++);
3736                 str->is_index_key = 1;
3737         }
3738 -       
3739 +
3740         /* try to find the string */
3741         if (-1 != (ndx = array_get_index(a, str->key->ptr, str->key->used, &pos))) {
3742                 /* found, leave here */
3743 @@ -181,14 +181,14 @@
3744                 }
3745                 return 0;
3746         }
3747 -       
3748 +
3749         /* insert */
3750 -       
3751 +
3752         if (a->used+1 > INT_MAX) {
3753                 /* we can't handle more then INT_MAX entries: see array_get_index() */
3754                 return -1;
3755         }
3756 -       
3757 +
3758         if (a->size == 0) {
3759                 a->size   = 16;
3760                 a->data   = malloc(sizeof(*a->data)     * a->size);
3761 @@ -204,27 +204,27 @@
3762                 assert(a->sorted);
3763                 for (j = a->used; j < a->size; j++) a->data[j] = NULL;
3764         }
3765 -       
3766 +
3767         ndx = (int) a->used;
3768 -       
3769 +
3770         a->data[a->used++] = str;
3771 -       
3772 +
3773         if (pos != ndx &&
3774 -           ((pos < 0) || 
3775 +           ((pos < 0) ||
3776              buffer_caseless_compare(str->key->ptr, str->key->used, a->data[a->sorted[pos]]->key->ptr, a->data[a->sorted[pos]]->key->used) > 0)) {
3777                 pos++;
3778 -       } 
3779 -       
3780 -       /* move everything on step to the right */
3781 +       }
3782 +
3783 +       /* move everything one step to the right */
3784         if (pos != ndx) {
3785                 memmove(a->sorted + (pos + 1), a->sorted + (pos), (ndx - pos) * sizeof(*a->sorted));
3786         }
3787 -       
3788 +
3789         /* insert */
3790         a->sorted[pos] = ndx;
3791 -       
3792 +
3793         if (a->next_power_of_2 == (size_t)ndx) a->next_power_of_2 <<= 1;
3794 -       
3795 +
3796         return 0;
3797  }
3798  
3799 @@ -254,7 +254,7 @@
3800         size_t i;
3801         size_t maxlen;
3802         int oneline = 1;
3803 -       
3804 +
3805         if (a->used > 5) {
3806                 oneline = 0;
3807         }
3808 @@ -314,7 +314,7 @@
3809         }
3810         array_print_indent(depth);
3811         fprintf(stderr, ")");
3812 -       
3813 +
3814         return 0;
3815  }
3816  
3817 @@ -323,47 +323,47 @@
3818         array *a;
3819         data_string *ds;
3820         data_count *dc;
3821 -       
3822 +
3823         UNUSED(argc);
3824         UNUSED(argv);
3825  
3826         a = array_init();
3827 -       
3828 +
3829         ds = data_string_init();
3830         buffer_copy_string(ds->key, "abc");
3831         buffer_copy_string(ds->value, "alfrag");
3832 -       
3833 +
3834         array_insert_unique(a, (data_unset *)ds);
3835 -       
3836 +
3837         ds = data_string_init();
3838         buffer_copy_string(ds->key, "abc");
3839         buffer_copy_string(ds->value, "hameplman");
3840 -       
3841 +
3842         array_insert_unique(a, (data_unset *)ds);
3843 -       
3844 +
3845         ds = data_string_init();
3846         buffer_copy_string(ds->key, "123");
3847         buffer_copy_string(ds->value, "alfrag");
3848 -       
3849 +
3850         array_insert_unique(a, (data_unset *)ds);
3851 -       
3852 +
3853         dc = data_count_init();
3854         buffer_copy_string(dc->key, "def");
3855 -       
3856 +
3857         array_insert_unique(a, (data_unset *)dc);
3858 -       
3859 +
3860         dc = data_count_init();
3861         buffer_copy_string(dc->key, "def");
3862 -       
3863 +
3864         array_insert_unique(a, (data_unset *)dc);
3865 -       
3866 +
3867         array_print(a, 0);
3868 -       
3869 +
3870         array_free(a);
3871 -       
3872 +
3873         fprintf(stderr, "%d\n",
3874                buffer_caseless_compare(CONST_STR_LEN("Content-Type"), CONST_STR_LEN("Content-type")));
3875 -       
3876 +
3877         return 0;
3878  }
3879  #endif
3880
3881 Property changes on: src/array.c
3882 ___________________________________________________________________
3883 Name: svn:eol-style
3884    + native
3885
3886 Index: src/mod_cml.h
3887 ===================================================================
3888 --- src/mod_cml.h       (.../tags/lighttpd-1.4.11)      (revision 1159)
3889 +++ src/mod_cml.h       (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
3890 @@ -16,10 +16,10 @@
3891  
3892  typedef struct {
3893         buffer *ext;
3894 -       
3895 +
3896         array  *mc_hosts;
3897         buffer *mc_namespace;
3898 -#if defined(HAVE_MEMCACHE_H) 
3899 +#if defined(HAVE_MEMCACHE_H)
3900         struct memcache *mc;
3901  #endif
3902         buffer *power_magnet;
3903 @@ -27,15 +27,15 @@
3904  
3905  typedef struct {
3906         PLUGIN_DATA;
3907 -       
3908 +
3909         buffer *basedir;
3910         buffer *baseurl;
3911 -       
3912 +
3913         buffer *trigger_handler;
3914 -       
3915 +
3916         plugin_config **config_storage;
3917 -       
3918 -       plugin_config conf; 
3919 +
3920 +       plugin_config conf;
3921  } plugin_data;
3922  
3923  int cache_parse_lua(server *srv, connection *con, plugin_data *p, buffer *fn);
3924
3925 Property changes on: src/mod_cml.h
3926 ___________________________________________________________________
3927 Name: svn:eol-style
3928    + native
3929
3930 Index: src/base.h
3931 ===================================================================
3932 --- src/base.h  (.../tags/lighttpd-1.4.11)      (revision 1159)
3933 +++ src/base.h  (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
3934 @@ -2,7 +2,6 @@
3935  #define _BASE_H_
3936  
3937  #include <sys/types.h>
3938 -#include <sys/time.h>
3939  #include <sys/stat.h>
3940  
3941  #ifdef HAVE_CONFIG_H
3942 @@ -26,10 +25,9 @@
3943  #include "sys-socket.h"
3944  #include "splaytree.h"
3945  
3946 -
3947  #if defined HAVE_LIBSSL && defined HAVE_OPENSSL_SSL_H
3948  # define USE_OPENSSL
3949 -# include <openssl/ssl.h> 
3950 +# include <openssl/ssl.h>
3951  #endif
3952  
3953  #ifdef HAVE_FAM_H
3954 @@ -40,10 +38,6 @@
3955  # define O_BINARY 0
3956  #endif
3957  
3958 -#ifndef O_LARGEFILE
3959 -# define O_LARGEFILE 0
3960 -#endif
3961 -
3962  #ifndef SIZE_MAX
3963  # ifdef SIZE_T_MAX
3964  #  define SIZE_MAX SIZE_T_MAX
3965 @@ -70,7 +64,8 @@
3966  
3967  /* solaris and NetBSD 1.3.x again */
3968  #if (!defined(HAVE_STDINT_H)) && (!defined(HAVE_INTTYPES_H)) && (!defined(uint32_t))
3969 -# define uint32_t u_int32_t
3970 +/* # define uint32_t u_int32_t */
3971 +typedef unsigned __int32 uint32_t;
3972  #endif
3973  
3974  
3975 @@ -80,24 +75,24 @@
3976  
3977  #include "settings.h"
3978  
3979 -typedef enum { T_CONFIG_UNSET, 
3980 -               T_CONFIG_STRING, 
3981 -               T_CONFIG_SHORT, 
3982 -               T_CONFIG_BOOLEAN, 
3983 -               T_CONFIG_ARRAY, 
3984 -               T_CONFIG_LOCAL, 
3985 +typedef enum { T_CONFIG_UNSET,
3986 +               T_CONFIG_STRING,
3987 +               T_CONFIG_SHORT,
3988 +               T_CONFIG_BOOLEAN,
3989 +               T_CONFIG_ARRAY,
3990 +               T_CONFIG_LOCAL,
3991                 T_CONFIG_DEPRECATED
3992  } config_values_type_t;
3993  
3994 -typedef enum { T_CONFIG_SCOPE_UNSET, 
3995 -               T_CONFIG_SCOPE_SERVER, 
3996 +typedef enum { T_CONFIG_SCOPE_UNSET,
3997 +               T_CONFIG_SCOPE_SERVER,
3998                 T_CONFIG_SCOPE_CONNECTION
3999  } config_scope_type_t;
4000  
4001  typedef struct {
4002         const char *key;
4003         void *destination;
4004 -       
4005 +
4006         config_values_type_t type;
4007         config_scope_type_t scope;
4008  } config_values_t;
4009 @@ -142,40 +137,40 @@
4010         /* the request-line */
4011         buffer *request;
4012         buffer *uri;
4013 -       
4014 +
4015         buffer *orig_uri;
4016 -       
4017 +
4018         http_method_t  http_method;
4019         http_version_t http_version;
4020 -       
4021 +
4022         buffer *request_line;
4023 -       
4024 +
4025         /* strings to the header */
4026         buffer *http_host; /* not alloced */
4027         const char   *http_range;
4028         const char   *http_content_type;
4029         const char   *http_if_modified_since;
4030         const char   *http_if_none_match;
4031 -       
4032 +
4033         array  *headers;
4034 -       
4035 +
4036         /* CONTENT */
4037         size_t content_length; /* returned by strtoul() */
4038 -       
4039 +
4040         /* internal representation */
4041         int     accept_encoding;
4042 -       
4043 +
4044         /* internal */
4045         buffer *pathinfo;
4046  } request;
4047  
4048  typedef struct {
4049         off_t   content_length;
4050 -       int     keep_alive;               /* used by  the subrequests in proxy, cgi and fcgi to say the subrequest was keep-alive or not */
4051 -       
4052 +       int     keep_alive;               /* used by the subrequests in proxy, cgi and fcgi to say whether the subrequest was keep-alive or not */
4053 +
4054         array  *headers;
4055 -       
4056 -       enum { 
4057 +
4058 +       enum {
4059                 HTTP_TRANSFER_ENCODING_IDENTITY, HTTP_TRANSFER_ENCODING_CHUNKED
4060         } transfer_encoding;
4061  } response;
4062 @@ -191,21 +186,21 @@
4063  typedef struct {
4064         buffer *path;
4065         buffer *basedir; /* path = "(basedir)(.*)" */
4066 -       
4067 +
4068         buffer *doc_root; /* path = doc_root + rel_path */
4069         buffer *rel_path;
4070 -       
4071 +
4072         buffer *etag;
4073  } physical;
4074  
4075  typedef struct {
4076         buffer *name;
4077         buffer *etag;
4078 -       
4079 +
4080         struct stat st;
4081 -       
4082 +
4083         time_t stat_ts;
4084 -       
4085 +
4086  #ifdef HAVE_FAM_H
4087         int    dir_version;
4088         int    dir_ndx;
4089 @@ -215,8 +210,8 @@
4090  } stat_cache_entry;
4091  
4092  typedef struct {
4093 -       splay_tree *files; /* the nodes of the tree are stat_cache_entry's */
4094 -       
4095 +       splay_tree *files; /* the nodes of the tree are stat_cache_entries */
4096 +
4097         buffer *dir_name; /* for building the dirname from the filename */
4098  #ifdef HAVE_FAM_H
4099         splay_tree *dirs; /* the nodes of the tree are fam_dir_entry */
4100 @@ -228,7 +223,7 @@
4101  
4102  typedef struct {
4103         array *mimetypes;
4104 -       
4105 +
4106         /* virtual-servers */
4107         buffer *document_root;
4108         buffer *server_name;
4109 @@ -236,7 +231,7 @@
4110         buffer *server_tag;
4111         buffer *dirlist_encoding;
4112         buffer *errorfile_prefix;
4113 -       
4114 +
4115         unsigned short max_keep_alive_requests;
4116         unsigned short max_keep_alive_idle;
4117         unsigned short max_read_idle;
4118 @@ -244,16 +239,17 @@
4119         unsigned short use_xattr;
4120         unsigned short follow_symlink;
4121         unsigned short range_requests;
4122 -       
4123 +
4124         /* debug */
4125 -       
4126 +
4127         unsigned short log_file_not_found;
4128         unsigned short log_request_header;
4129         unsigned short log_request_handling;
4130         unsigned short log_response_header;
4131         unsigned short log_condition_handling;
4132 -       
4133 -       
4134 +       unsigned short log_condition_cache_handling;
4135 +
4136 +
4137         /* server wide */
4138         buffer *ssl_pemfile;
4139         buffer *ssl_ca_file;
4140 @@ -268,22 +264,22 @@
4141         /* configside */
4142         unsigned short global_kbytes_per_second; /*  */
4143  
4144 -       off_t  global_bytes_per_second_cnt; 
4145 +       off_t  global_bytes_per_second_cnt;
4146         /* server-wide traffic-shaper
4147 -        * 
4148 +        *
4149          * each context has the counter which is inited once
4150 -        * a second by the global_kbytes_per_second config-var
4151 +        * per second by the global_kbytes_per_second config-var
4152          *
4153          * as soon as global_kbytes_per_second gets below 0
4154          * the connected conns are "offline" a little bit
4155          *
4156          * the problem:
4157 -        * we somehow have to loose our "we are writable" signal 
4158 +        * we somehow have to lose our "we are writable" signal
4159          * on the way.
4160 -        * 
4161 +        *
4162          */
4163         off_t *global_bytes_per_second_cnt_ptr; /*  */
4164 -       
4165 +
4166  #ifdef USE_OPENSSL
4167         SSL_CTX *ssl_ctx;
4168  #endif
4169 @@ -291,18 +287,18 @@
4170  
4171  /* the order of the items should be the same as they are processed
4172   * read before write as we use this later */
4173 -typedef enum { 
4174 -       CON_STATE_CONNECT, 
4175 -       CON_STATE_REQUEST_START, 
4176 -       CON_STATE_READ, 
4177 -       CON_STATE_REQUEST_END, 
4178 -       CON_STATE_READ_POST, 
4179 -       CON_STATE_HANDLE_REQUEST, 
4180 -       CON_STATE_RESPONSE_START, 
4181 -       CON_STATE_WRITE, 
4182 -       CON_STATE_RESPONSE_END, 
4183 -       CON_STATE_ERROR, 
4184 -       CON_STATE_CLOSE 
4185 +typedef enum {
4186 +       CON_STATE_CONNECT,
4187 +       CON_STATE_REQUEST_START,
4188 +       CON_STATE_READ,
4189 +       CON_STATE_REQUEST_END,
4190 +       CON_STATE_READ_POST,
4191 +       CON_STATE_HANDLE_REQUEST,
4192 +       CON_STATE_RESPONSE_START,
4193 +       CON_STATE_WRITE,
4194 +       CON_STATE_RESPONSE_END,
4195 +       CON_STATE_ERROR,
4196 +       CON_STATE_CLOSE
4197  } connection_state_t;
4198  
4199  typedef enum { COND_RESULT_UNSET, COND_RESULT_FALSE, COND_RESULT_TRUE } cond_result_t;
4200 @@ -315,88 +311,88 @@
4201  
4202  typedef struct {
4203         connection_state_t state;
4204 -       
4205 +
4206         /* timestamps */
4207         time_t read_idle_ts;
4208         time_t close_timeout_ts;
4209         time_t write_request_ts;
4210 -       
4211 +
4212         time_t connection_start;
4213         time_t request_start;
4214 -       
4215 +
4216         struct timeval start_tv;
4217 -       
4218 +
4219         size_t request_count;        /* number of requests handled in this connection */
4220         size_t loops_per_request;    /* to catch endless loops in a single request
4221 -                                     * 
4222 +                                     *
4223                                       * used by mod_rewrite, mod_fastcgi, ... and others
4224                                       * this is self-protection
4225                                       */
4226 -       
4227 +
4228         int fd;                      /* the FD for this connection */
4229         int fde_ndx;                 /* index for the fdevent-handler */
4230         int ndx;                     /* reverse mapping to server->connection[ndx] */
4231 -       
4232 +
4233         /* fd states */
4234         int is_readable;
4235         int is_writable;
4236 -       
4237 -       int     keep_alive;           /* only request.c can enable it, all other just disable */
4238 -       
4239 +
4240 +       int     keep_alive;           /* only request.c can enable it, all others just disable */
4241 +
4242         int file_started;
4243         int file_finished;
4244 -       
4245 +
4246         chunkqueue *write_queue;      /* a large queue for low-level write ( HTTP response ) [ file, mem ] */
4247         chunkqueue *read_queue;       /* a small queue for low-level read ( HTTP request ) [ mem ] */
4248         chunkqueue *request_content_queue; /* takes request-content into tempfile if necessary [ tempfile, mem ]*/
4249 -       
4250 +
4251         int traffic_limit_reached;
4252 -       
4253 +
4254         off_t bytes_written;          /* used by mod_accesslog, mod_rrd */
4255         off_t bytes_written_cur_second; /* used by mod_accesslog, mod_rrd */
4256         off_t bytes_read;             /* used by mod_accesslog, mod_rrd */
4257         off_t bytes_header;
4258 -       
4259 +
4260         int http_status;
4261 -       
4262 +
4263         sock_addr dst_addr;
4264         buffer *dst_addr_buf;
4265  
4266         /* request */
4267         buffer *parse_request;
4268         unsigned int parsed_response; /* bitfield which contains the important header-fields of the parsed response header */
4269 -       
4270 +
4271         request  request;
4272         request_uri uri;
4273 -       physical physical; 
4274 +       physical physical;
4275         response response;
4276 -       
4277 +
4278         size_t header_len;
4279 -       
4280 +
4281         buffer *authed_user;
4282         array  *environment; /* used to pass lighttpd internal stuff to the FastCGI/CGI apps, setenv does that */
4283 -       
4284 +
4285         /* response */
4286         int    got_response;
4287 -       
4288 +
4289         int    in_joblist;
4290 -       
4291 +
4292         connection_type mode;
4293 -       
4294 +
4295         void **plugin_ctx;           /* plugin connection specific config */
4296 -       
4297 +
4298         specific_config conf;        /* global connection specific config */
4299         cond_cache_t *cond_cache;
4300 -       
4301 +
4302         buffer *server_name;
4303 -       
4304 +
4305         /* error-handler */
4306         buffer *error_handler;
4307         int error_handler_saved_status;
4308         int in_error_handler;
4309 -       
4310 +
4311         void *srv_socket;   /* reference to the server-socket (typecast to server_socket) */
4312 -       
4313 +
4314  #ifdef USE_OPENSSL
4315         SSL *ssl;
4316  #endif
4317 @@ -439,39 +435,48 @@
4318         size_t size;
4319  } buffer_plugin;
4320  
4321 +typedef enum {
4322 +    NETWORK_STATUS_UNSET,
4323 +    NETWORK_STATUS_SUCCESS,
4324 +    NETWORK_STATUS_FATAL_ERROR,
4325 +    NETWORK_STATUS_CONNECTION_CLOSE,
4326 +    NETWORK_STATUS_WAIT_FOR_EVENT,
4327 +    NETWORK_STATUS_INTERRUPTED
4328 +} network_status_t;
4329 +
4330  typedef struct {
4331         unsigned short port;
4332         buffer *bindhost;
4333 -       
4334 +
4335         buffer *errorlog_file;
4336         unsigned short errorlog_use_syslog;
4337 -       
4338 +
4339         unsigned short dont_daemonize;
4340         buffer *changeroot;
4341         buffer *username;
4342         buffer *groupname;
4343 -       
4344 +
4345         buffer *pid_file;
4346 -       
4347 +
4348         buffer *event_handler;
4349 -       
4350 +
4351         buffer *modules_dir;
4352         buffer *network_backend;
4353         array *modules;
4354         array *upload_tempdirs;
4355 -       
4356 +
4357         unsigned short max_worker;
4358         unsigned short max_fds;
4359         unsigned short max_conns;
4360         unsigned short max_request_size;
4361 -       
4362 +
4363         unsigned short log_request_header_on_error;
4364         unsigned short log_state_handling;
4365 -       
4366 -       enum { STAT_CACHE_ENGINE_UNSET, 
4367 -                       STAT_CACHE_ENGINE_NONE, 
4368 -                       STAT_CACHE_ENGINE_SIMPLE, 
4369 -                       STAT_CACHE_ENGINE_FAM 
4370 +
4371 +       enum { STAT_CACHE_ENGINE_UNSET,
4372 +                       STAT_CACHE_ENGINE_NONE,
4373 +                       STAT_CACHE_ENGINE_SIMPLE,
4374 +                       STAT_CACHE_ENGINE_FAM
4375         } stat_cache_engine;
4376         unsigned short enable_cores;
4377  } server_config;
4378 @@ -480,14 +485,14 @@
4379         sock_addr addr;
4380         int       fd;
4381         int       fde_ndx;
4382 -       
4383 +
4384         buffer *ssl_pemfile;
4385         buffer *ssl_ca_file;
4386         unsigned short use_ipv6;
4387         unsigned short is_ssl;
4388 -       
4389 +
4390         buffer *srv_token;
4391 -       
4392 +
4393  #ifdef USE_OPENSSL
4394         SSL_CTX *ssl_ctx;
4395  #endif
4396 @@ -495,37 +500,37 @@
4397  
4398  typedef struct {
4399         server_socket **ptr;
4400 -       
4401 +
4402         size_t size;
4403         size_t used;
4404  } server_socket_array;
4405  
4406  typedef struct server {
4407         server_socket_array srv_sockets;
4408 -       
4409 +
4410         /* the errorlog */
4411         int errorlog_fd;
4412         enum { ERRORLOG_STDERR, ERRORLOG_FILE, ERRORLOG_SYSLOG } errorlog_mode;
4413         buffer *errorlog_buf;
4414 -       
4415 +
4416         fdevents *ev, *ev_ins;
4417 -       
4418 +
4419         buffer_plugin plugins;
4420         void *plugin_slots;
4421 -       
4422 +
4423         /* counters */
4424         int con_opened;
4425         int con_read;
4426         int con_written;
4427         int con_closed;
4428 -       
4429 +
4430         int ssl_is_init;
4431 -       
4432 +
4433         int max_fds;    /* max possible fds */
4434         int cur_fds;    /* currently used fds */
4435         int want_fds;   /* waiting fds */
4436         int sockets_disabled;
4437 -       
4438 +
4439         size_t max_conns;
4440  
4441         /* buffers */
4442 @@ -533,13 +538,13 @@
4443         buffer *response_header;
4444         buffer *response_range;
4445         buffer *tmp_buf;
4446 -       
4447 +
4448         buffer *tmp_chunk_len;
4449 -       
4450 +
4451         buffer *empty_string; /* is necessary for cond_match */
4452  
4453         buffer *cond_check_buf;
4454 -       
4455 +
4456         /* caches */
4457  #ifdef HAVE_IPV6
4458         inet_ntop_cache_type inet_ntop_cache[INET_NTOP_CACHE_MAX];
4459 @@ -547,31 +552,31 @@
4460         mtime_cache_type mtime_cache[FILE_CACHE_MAX];
4461  
4462         array *split_vals;
4463 -       
4464 +
4465         /* Timestamps */
4466         time_t cur_ts;
4467         time_t last_generated_date_ts;
4468         time_t last_generated_debug_ts;
4469         time_t startup_ts;
4470 -       
4471 +
4472         buffer *ts_debug_str;
4473         buffer *ts_date_str;
4474 -       
4475 +
4476         /* config-file */
4477         array *config;
4478         array *config_touched;
4479 -       
4480 +
4481         array *config_context;
4482         specific_config **config_storage;
4483 -       
4484 +
4485         server_config  srvconf;
4486 -       
4487 +
4488         int config_deprecated;
4489 -       
4490 +
4491         connections *conns;
4492         connections *joblist;
4493         connections *fdwaitqueue;
4494 -       
4495 +
4496         stat_cache  *stat_cache;
4497  
4498         /**
4499 @@ -588,18 +593,20 @@
4500          *   fastcgi.backend.<key>.disconnects = ...
4501          */
4502         array *status;
4503 -       
4504 +
4505         fdevent_handler_t event_handler;
4506  
4507 -       int (* network_backend_write)(struct server *srv, connection *con, int fd, chunkqueue *cq);
4508 -       int (* network_backend_read)(struct server *srv, connection *con, int fd, chunkqueue *cq);
4509 +       network_status_t (* network_backend_write)(struct server *srv, connection *con, int fd, chunkqueue *cq);
4510 +       network_status_t (* network_backend_read)(struct server *srv, connection *con, int fd, chunkqueue *cq);
4511  #ifdef USE_OPENSSL
4512 -       int (* network_ssl_backend_write)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq);
4513 -       int (* network_ssl_backend_read)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq);
4514 +       network_status_t (* network_ssl_backend_write)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq);
4515 +       network_status_t (* network_ssl_backend_read)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq);
4516  #endif
4517  
4518 +#ifdef HAVE_PWD_H
4519         uid_t uid;
4520         gid_t gid;
4521 +#endif
4522  } server;
4523  
4524  
4525
4526 Property changes on: src/base.h
4527 ___________________________________________________________________
4528 Name: svn:eol-style
4529    + native
4530
4531 Index: src/mod_rewrite.c
4532 ===================================================================
4533 --- src/mod_rewrite.c   (.../tags/lighttpd-1.4.11)      (revision 1159)
4534 +++ src/mod_rewrite.c   (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
4535 @@ -13,24 +13,8 @@
4536  #endif
4537  
4538  typedef struct {
4539 -#ifdef HAVE_PCRE_H
4540 -       pcre *key;
4541 -#endif
4542 -       
4543 -       buffer *value;
4544 -       
4545 -       int once;
4546 -} rewrite_rule;
4547 -
4548 -typedef struct {
4549 -       rewrite_rule **ptr;
4550 -       
4551 -       size_t used;
4552 -       size_t size;
4553 -} rewrite_rule_buffer;
4554 -
4555 -typedef struct {
4556 -       rewrite_rule_buffer *rewrite;
4557 +       pcre_keyvalue_buffer *rewrite;
4558 +       buffer *once;
4559         data_config *context; /* to which apply me */
4560  } plugin_config;
4561  
4562 @@ -42,20 +26,20 @@
4563  typedef struct {
4564         PLUGIN_DATA;
4565         buffer *match_buf;
4566 -       
4567 +
4568         plugin_config **config_storage;
4569 -       
4570 -       plugin_config conf; 
4571 +
4572 +       plugin_config conf;
4573  } plugin_data;
4574  
4575  static handler_ctx * handler_ctx_init() {
4576         handler_ctx * hctx;
4577 -       
4578 +
4579         hctx = calloc(1, sizeof(*hctx));
4580 -       
4581 +
4582         hctx->state = REWRITE_STATE_UNSET;
4583         hctx->loops = 0;
4584 -       
4585 +
4586         return hctx;
4587  }
4588  
4589 @@ -63,207 +47,136 @@
4590         free(hctx);
4591  }
4592  
4593 -rewrite_rule_buffer *rewrite_rule_buffer_init(void) {
4594 -       rewrite_rule_buffer *kvb;
4595 -       
4596 -       kvb = calloc(1, sizeof(*kvb));
4597 -       
4598 -       return kvb;
4599 -}
4600  
4601 -int rewrite_rule_buffer_append(rewrite_rule_buffer *kvb, buffer *key, buffer *value, int once) {
4602 -#ifdef HAVE_PCRE_H
4603 -       size_t i;
4604 -       const char *errptr;
4605 -       int erroff;
4606 -       
4607 -       if (!key) return -1;
4608 -
4609 -       if (kvb->size == 0) {
4610 -               kvb->size = 4;
4611 -               kvb->used = 0;
4612 -               
4613 -               kvb->ptr = malloc(kvb->size * sizeof(*kvb->ptr));
4614 -               
4615 -               for(i = 0; i < kvb->size; i++) {
4616 -                       kvb->ptr[i] = calloc(1, sizeof(**kvb->ptr));
4617 -               }
4618 -       } else if (kvb->used == kvb->size) {
4619 -               kvb->size += 4;
4620 -               
4621 -               kvb->ptr = realloc(kvb->ptr, kvb->size * sizeof(*kvb->ptr));
4622 -               
4623 -               for(i = kvb->used; i < kvb->size; i++) {
4624 -                       kvb->ptr[i] = calloc(1, sizeof(**kvb->ptr));
4625 -               }
4626 -       }
4627 -       
4628 -       if (NULL == (kvb->ptr[kvb->used]->key = pcre_compile(key->ptr,
4629 -                                                           0, &errptr, &erroff, NULL))) {
4630 -               
4631 -               return -1;
4632 -       }
4633 -       
4634 -       kvb->ptr[kvb->used]->value = buffer_init();
4635 -       buffer_copy_string_buffer(kvb->ptr[kvb->used]->value, value);
4636 -       kvb->ptr[kvb->used]->once = once;
4637 -       
4638 -       kvb->used++;
4639 -       
4640 -       return 0;
4641 -#else
4642 -       UNUSED(kvb);
4643 -       UNUSED(value);
4644 -       UNUSED(once);
4645 -       UNUSED(key);
4646 -
4647 -       return -1;
4648 -#endif
4649 -}
4650 -
4651 -void rewrite_rule_buffer_free(rewrite_rule_buffer *kvb) {
4652 -#ifdef HAVE_PCRE_H
4653 -       size_t i;
4654 -
4655 -       for (i = 0; i < kvb->size; i++) {
4656 -               if (kvb->ptr[i]->key) pcre_free(kvb->ptr[i]->key);
4657 -               if (kvb->ptr[i]->value) buffer_free(kvb->ptr[i]->value);
4658 -               free(kvb->ptr[i]);
4659 -       }
4660 -       
4661 -       if (kvb->ptr) free(kvb->ptr);
4662 -#endif
4663 -       
4664 -       free(kvb);
4665 -}
4666 -
4667 -
4668  INIT_FUNC(mod_rewrite_init) {
4669         plugin_data *p;
4670 -       
4671 +
4672         p = calloc(1, sizeof(*p));
4673 -       
4674 +
4675         p->match_buf = buffer_init();
4676 -       
4677 +
4678         return p;
4679  }
4680  
4681  FREE_FUNC(mod_rewrite_free) {
4682         plugin_data *p = p_d;
4683 -       
4684 +
4685         UNUSED(srv);
4686  
4687         if (!p) return HANDLER_GO_ON;
4688 -       
4689 +
4690         buffer_free(p->match_buf);
4691         if (p->config_storage) {
4692                 size_t i;
4693                 for (i = 0; i < srv->config_context->used; i++) {
4694                         plugin_config *s = p->config_storage[i];
4695 -                       rewrite_rule_buffer_free(s->rewrite);
4696 -                       
4697 +                       pcre_keyvalue_buffer_free(s->rewrite);
4698 +                       buffer_free(s->once);
4699 +
4700                         free(s);
4701                 }
4702                 free(p->config_storage);
4703         }
4704 -       
4705 +
4706         free(p);
4707 -       
4708 +
4709         return HANDLER_GO_ON;
4710  }
4711  
4712  static int parse_config_entry(server *srv, plugin_config *s, array *ca, const char *option, int once) {
4713         data_unset *du;
4714 -       
4715 +
4716         if (NULL != (du = array_get_element(ca, option))) {
4717                 data_array *da = (data_array *)du;
4718                 size_t j;
4719 -               
4720 +
4721                 if (du->type != TYPE_ARRAY) {
4722 -                       log_error_write(srv, __FILE__, __LINE__, "sss", 
4723 +                       log_error_write(srv, __FILE__, __LINE__, "sss",
4724                                         "unexpected type for key: ", option, "array of strings");
4725 -                       
4726 +
4727                         return HANDLER_ERROR;
4728                 }
4729 -               
4730 +
4731                 da = (data_array *)du;
4732 -               
4733 +
4734                 for (j = 0; j < da->value->used; j++) {
4735                         if (da->value->data[j]->type != TYPE_STRING) {
4736 -                               log_error_write(srv, __FILE__, __LINE__, "sssbs", 
4737 -                                               "unexpected type for key: ", 
4738 -                                               option, 
4739 +                               log_error_write(srv, __FILE__, __LINE__, "sssbs",
4740 +                                               "unexpected type for key: ",
4741 +                                               option,
4742                                                 "[", da->value->data[j]->key, "](string)");
4743 -                               
4744 +
4745                                 return HANDLER_ERROR;
4746                         }
4747 -                       
4748 -                       if (0 != rewrite_rule_buffer_append(s->rewrite, 
4749 -                                                           ((data_string *)(da->value->data[j]))->key,
4750 -                                                           ((data_string *)(da->value->data[j]))->value,
4751 -                                                           once)) {
4752 +
4753 +                       if (0 != pcre_keyvalue_buffer_append(s->rewrite,
4754 +                                                           ((data_string *)(da->value->data[j]))->key->ptr,
4755 +                                                           ((data_string *)(da->value->data[j]))->value->ptr)) {
4756  #ifdef HAVE_PCRE_H
4757 -                               log_error_write(srv, __FILE__, __LINE__, "sb", 
4758 +                               log_error_write(srv, __FILE__, __LINE__, "sb",
4759                                                 "pcre-compile failed for", da->value->data[j]->key);
4760  #else
4761 -                               log_error_write(srv, __FILE__, __LINE__, "s", 
4762 +                               log_error_write(srv, __FILE__, __LINE__, "s",
4763                                                 "pcre support is missing, please install libpcre and the headers");
4764  #endif
4765                         }
4766 +
4767 +                       if (once) {
4768 +                               buffer_append_string_len(s->once, CONST_STR_LEN("1"));
4769 +                       } else {
4770 +                               buffer_append_string_len(s->once, CONST_STR_LEN("0"));
4771 +                       }
4772                 }
4773         }
4774 -       
4775 +
4776         return 0;
4777  }
4778  
4779  SETDEFAULTS_FUNC(mod_rewrite_set_defaults) {
4780         plugin_data *p = p_d;
4781         size_t i = 0;
4782 -       
4783 -       config_values_t cv[] = { 
4784 +
4785 +       config_values_t cv[] = {
4786                 { "url.rewrite-repeat",        NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
4787                 { "url.rewrite-once",          NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
4788 -               
4789 -               /* old names, still supported 
4790 -                * 
4791 +
4792 +               /* old names, still supported
4793 +                *
4794                  * url.rewrite remapped to url.rewrite-once
4795                  * url.rewrite-final    is url.rewrite-once
4796 -                * 
4797 +                *
4798                  */
4799                 { "url.rewrite",               NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
4800                 { "url.rewrite-final",         NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 3 */
4801                 { NULL,                        NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
4802         };
4803 -       
4804 +
4805         if (!p) return HANDLER_ERROR;
4806 -       
4807 +
4808         /* 0 */
4809         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
4810 -       
4811 +
4812         for (i = 0; i < srv->config_context->used; i++) {
4813                 plugin_config *s;
4814                 array *ca;
4815 -               
4816 +
4817                 s = calloc(1, sizeof(plugin_config));
4818 -               s->rewrite   = rewrite_rule_buffer_init();
4819 -               
4820 -               cv[0].destination = s->rewrite;
4821 -               cv[1].destination = s->rewrite;
4822 -               cv[2].destination = s->rewrite;
4823 -               
4824 +               s->rewrite   = pcre_keyvalue_buffer_init();
4825 +               s->once      = buffer_init();
4826 +
4827                 p->config_storage[i] = s;
4828                 ca = ((data_config *)srv->config_context->data[i])->value;
4829 -       
4830 +
4831                 if (0 != config_insert_values_global(srv, ca, cv)) {
4832                         return HANDLER_ERROR;
4833                 }
4834 -               
4835 +
4836                 parse_config_entry(srv, s, ca, "url.rewrite-once",   1);
4837                 parse_config_entry(srv, s, ca, "url.rewrite-final",  1);
4838                 parse_config_entry(srv, s, ca, "url.rewrite",        1);
4839                 parse_config_entry(srv, s, ca, "url.rewrite-repeat", 0);
4840         }
4841 -       
4842 +
4843         return HANDLER_GO_ON;
4844  }
4845  #ifdef HAVE_PCRE_H
4846 @@ -271,157 +184,107 @@
4847         size_t i, j;
4848         plugin_config *s = p->config_storage[0];
4849         p->conf.rewrite = s->rewrite;
4850 -       
4851 +       p->conf.once    = s->once;
4852 +
4853         /* skip the first, the global context */
4854         for (i = 1; i < srv->config_context->used; i++) {
4855                 data_config *dc = (data_config *)srv->config_context->data[i];
4856                 s = p->config_storage[i];
4857 -               
4858 +
4859                 if (COMP_HTTP_URL == dc->comp) continue;
4860 -               
4861 +
4862                 /* condition didn't match */
4863                 if (!config_check_cond(srv, con, dc)) continue;
4864 -               
4865 +
4866                 /* merge config */
4867                 for (j = 0; j < dc->value->used; j++) {
4868                         data_unset *du = dc->value->data[j];
4869 -                       
4870 +
4871                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.rewrite"))) {
4872                                 p->conf.rewrite = s->rewrite;
4873 +                               p->conf.once    = s->once;
4874                                 p->conf.context = dc;
4875                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.rewrite-once"))) {
4876                                 p->conf.rewrite = s->rewrite;
4877 +                               p->conf.once    = s->once;
4878                                 p->conf.context = dc;
4879                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.rewrite-repeat"))) {
4880                                 p->conf.rewrite = s->rewrite;
4881 +                               p->conf.once    = s->once;
4882                                 p->conf.context = dc;
4883                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.rewrite-final"))) {
4884                                 p->conf.rewrite = s->rewrite;
4885 +                               p->conf.once    = s->once;
4886                                 p->conf.context = dc;
4887                         }
4888                 }
4889         }
4890 -       
4891 +
4892         return 0;
4893  }
4894  #endif
4895  URIHANDLER_FUNC(mod_rewrite_con_reset) {
4896         plugin_data *p = p_d;
4897 -       
4898 +
4899         UNUSED(srv);
4900 -       
4901 +
4902         if (con->plugin_ctx[p->id]) {
4903                 handler_ctx_free(con->plugin_ctx[p->id]);
4904                 con->plugin_ctx[p->id] = NULL;
4905         }
4906 -       
4907 +
4908         return HANDLER_GO_ON;
4909  }
4910  
4911  URIHANDLER_FUNC(mod_rewrite_uri_handler) {
4912  #ifdef HAVE_PCRE_H
4913         plugin_data *p = p_d;
4914 -       size_t i;
4915 +       int i;
4916         handler_ctx *hctx;
4917  
4918 -       /* 
4919 +       /*
4920          * REWRITE URL
4921 -        * 
4922 +        *
4923          * e.g. rewrite /base/ to /index.php?section=base
4924 -        * 
4925 +        *
4926          */
4927 -       
4928 +
4929         if (con->plugin_ctx[p->id]) {
4930                 hctx = con->plugin_ctx[p->id];
4931 -               
4932 +
4933                 if (hctx->loops++ > 100) {
4934 -                       log_error_write(srv, __FILE__, __LINE__,  "s",  
4935 +                       log_error_write(srv, __FILE__, __LINE__,  "s",
4936                                         "ENDLESS LOOP IN rewrite-rule DETECTED ... aborting request, perhaps you want to use url.rewrite-once instead of url.rewrite-repeat");
4937 -                       
4938 +
4939                         return HANDLER_ERROR;
4940                 }
4941 -               
4942 +
4943                 if (hctx->state == REWRITE_STATE_FINISHED) return HANDLER_GO_ON;
4944         }
4945 -       
4946 +
4947         mod_rewrite_patch_connection(srv, con, p);
4948  
4949         if (!p->conf.rewrite) return HANDLER_GO_ON;
4950 -       
4951 +
4952         buffer_copy_string_buffer(p->match_buf, con->request.uri);
4953 -       
4954 -       for (i = 0; i < p->conf.rewrite->used; i++) {
4955 -               pcre *match;
4956 -               const char *pattern;
4957 -               size_t pattern_len;
4958 -               int n;
4959 -               rewrite_rule *rule = p->conf.rewrite->ptr[i];
4960 -# define N 10
4961 -               int ovec[N * 3];
4962 -               
4963 -               match       = rule->key;
4964 -               pattern     = rule->value->ptr;
4965 -               pattern_len = rule->value->used - 1;
4966 -               
4967 -               if ((n = pcre_exec(match, NULL, p->match_buf->ptr, p->match_buf->used - 1, 0, 0, ovec, 3 * N)) < 0) {
4968 -                       if (n != PCRE_ERROR_NOMATCH) {
4969 -                               log_error_write(srv, __FILE__, __LINE__, "sd",
4970 -                                               "execution error while matching: ", n);
4971 -                               return HANDLER_ERROR;
4972 -                       }
4973 -               } else {
4974 -                       const char **list;
4975 -                       size_t start, end;
4976 -                       size_t k;
4977 -                       
4978 -                       /* it matched */
4979 -                       pcre_get_substring_list(p->match_buf->ptr, ovec, n, &list);
4980 -                       
4981 -                       /* search for $[0-9] */
4982 -                       
4983 -                       buffer_reset(con->request.uri);
4984 -                       
4985 -                       start = 0; end = pattern_len;
4986 -                       for (k = 0; k < pattern_len; k++) {
4987 -                               if ((pattern[k] == '$' || pattern[k] == '%') &&
4988 -                                   isdigit((unsigned char)pattern[k + 1])) {
4989 -                                       /* got one */
4990 -                                       
4991 -                                       size_t num = pattern[k + 1] - '0';
4992 -                                       
4993 -                                       end = k;
4994 -                                       
4995 -                                       buffer_append_string_len(con->request.uri, pattern + start, end - start);
4996 -                                       
4997 -                                       if (pattern[k] == '$') {
4998 -                                               /* n is always > 0 */
4999 -                                               if (num < (size_t)n) {
5000 -                                                       buffer_append_string(con->request.uri, list[num]);
5001 -                                               }
5002 -                                       } else {
5003 -                                               config_append_cond_match_buffer(con, p->conf.context, con->request.uri, num);
5004 -                                       }
5005 -                                       
5006 -                                       k++;
5007 -                                       start = k + 1;
5008 -                               } 
5009 -                       }
5010 -                       
5011 -                       buffer_append_string_len(con->request.uri, pattern + start, pattern_len - start);
5012 -                       
5013 -                       pcre_free(list);
5014 -                       
5015 -                       hctx = handler_ctx_init();
5016 -                               
5017 -                       con->plugin_ctx[p->id] = hctx;
5018 -                       
5019 -                       if (rule->once) hctx->state = REWRITE_STATE_FINISHED;
5020 -                       
5021 -                       return HANDLER_COMEBACK;
5022 -               }
5023 +       i = config_exec_pcre_keyvalue_buffer(con, p->conf.rewrite, p->conf.context, p->match_buf, con->request.uri);
5024 +
5025 +       if (i >= 0) {
5026 +               hctx = handler_ctx_init();
5027 +
5028 +               con->plugin_ctx[p->id] = hctx;
5029 +
5030 +               if (p->conf.once->ptr[i] == '1')
5031 +                       hctx->state = REWRITE_STATE_FINISHED;
5032 +
5033 +               return HANDLER_COMEBACK;
5034         }
5035 +       else if (i != PCRE_ERROR_NOMATCH) {
5036 +               log_error_write(srv, __FILE__, __LINE__, "s",
5037 +                               "execution error while matching", i);
5038 +       }
5039  #undef N
5040 -               
5041 +
5042  #else
5043         UNUSED(srv);
5044         UNUSED(con);
5045 @@ -434,17 +297,17 @@
5046  int mod_rewrite_plugin_init(plugin *p) {
5047         p->version     = LIGHTTPD_VERSION_ID;
5048         p->name        = buffer_init_string("rewrite");
5049 -       
5050 +
5051         p->init        = mod_rewrite_init;
5052         /* it has to stay _raw as we are matching on uri + querystring
5053          */
5054 -       
5055 +
5056         p->handle_uri_raw = mod_rewrite_uri_handler;
5057         p->set_defaults = mod_rewrite_set_defaults;
5058         p->cleanup     = mod_rewrite_free;
5059         p->connection_reset = mod_rewrite_con_reset;
5060 -       
5061 +
5062         p->data        = NULL;
5063 -       
5064 +
5065         return 0;
5066  }
5067
5068 Property changes on: src/mod_rewrite.c
5069 ___________________________________________________________________
5070 Name: svn:eol-style
5071    + native
5072
5073 Index: src/lempar.c
5074 ===================================================================
5075 --- src/lempar.c        (.../tags/lighttpd-1.4.11)      (revision 1159)
5076 +++ src/lempar.c        (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
5077 @@ -8,10 +8,10 @@
5078  /* Next is all token values, in a form suitable for use by makeheaders.
5079  ** This section will be null unless lemon is run with the -m switch.
5080  */
5081 -/* 
5082 +/*
5083  ** These constants (all generated automatically by the parser generator)
5084  ** specify the various kinds of tokens (terminals) that the parser
5085 -** understands. 
5086 +** understands.
5087  **
5088  ** Each symbol here is a terminal symbol in the grammar.
5089  */
5090 @@ -29,7 +29,7 @@
5091  **                       and nonterminals.  "int" is used otherwise.
5092  **    YYNOCODE           is a number of type YYCODETYPE which corresponds
5093  **                       to no legal terminal or nonterminal number.  This
5094 -**                       number is used to fill in empty slots of the hash 
5095 +**                       number is used to fill in empty slots of the hash
5096  **                       table.
5097  **    YYFALLBACK         If defined, this indicates that one or more tokens
5098  **                       have fall-back values which should be used if the
5099 @@ -38,7 +38,7 @@
5100  **                       and nonterminal numbers.  "unsigned char" is
5101  **                       used if there are fewer than 250 rules and
5102  **                       states combined.  "int" is used otherwise.
5103 -**    ParseTOKENTYPE     is the data type used for minor tokens given 
5104 +**    ParseTOKENTYPE     is the data type used for minor tokens given
5105  **                       directly to the parser from the tokenizer.
5106  **    YYMINORTYPE        is the data type used for all minor tokens.
5107  **                       This is typically a union of many types, one of
5108 @@ -62,7 +62,7 @@
5109  /* Next are that tables used to determine what action to take based on the
5110  ** current state and lookahead token.  These tables are used to implement
5111  ** functions that take a state number and lookahead value and return an
5112 -** action integer.  
5113 +** action integer.
5114  **
5115  ** Suppose the action integer is N.  Then the action is determined as
5116  ** follows
5117 @@ -87,7 +87,7 @@
5118  ** If the index value yy_shift_ofst[S]+X is out of range or if the value
5119  ** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S]
5120  ** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
5121 -** and that yy_default[S] should be used instead.  
5122 +** and that yy_default[S] should be used instead.
5123  **
5124  ** The formula above is for computing the action when the lookahead is
5125  ** a terminal symbol.  If the lookahead is a non-terminal (as occurs after
5126 @@ -111,7 +111,7 @@
5127  
5128  /* The next table maps tokens into fallback tokens.  If a construct
5129  ** like the following:
5130 -** 
5131 +**
5132  **      %fallback ID X Y Z.
5133  **
5134  ** appears in the grammer, then ID becomes a fallback token for X, Y,
5135 @@ -163,10 +163,10 @@
5136  #endif /* NDEBUG */
5137  
5138  #ifndef NDEBUG
5139 -/* 
5140 +/*
5141  ** Turn parser tracing on by giving a stream to which to write the trace
5142  ** and a prompt to preface each trace message.  Tracing is turned off
5143 -** by making either argument NULL 
5144 +** by making either argument NULL
5145  **
5146  ** Inputs:
5147  ** <ul>
5148 @@ -191,7 +191,7 @@
5149  #ifndef NDEBUG
5150  /* For tracing shifts, the names of all terminals and nonterminals
5151  ** are required.  The following table supplies these names */
5152 -static const char *yyTokenName[] = { 
5153 +static const char *yyTokenName[] = {
5154  %%
5155  };
5156  #endif /* NDEBUG */
5157 @@ -220,7 +220,7 @@
5158  #endif
5159  }
5160  
5161 -/* 
5162 +/*
5163  ** This function allocates a new parser.
5164  ** The only argument is a pointer to a function which works like
5165  ** malloc.
5166 @@ -251,7 +251,7 @@
5167      /* Here is inserted the actions which take place when a
5168      ** terminal or non-terminal is destroyed.  This can happen
5169      ** when the symbol is popped from the stack during a
5170 -    ** reduce or during error processing or when a parser is 
5171 +    ** reduce or during error processing or when a parser is
5172      ** being destroyed before it is finished parsing.
5173      **
5174      ** Note: during a reduce, the only symbols destroyed are those
5175 @@ -289,7 +289,7 @@
5176    return yymajor;
5177  }
5178  
5179 -/* 
5180 +/*
5181  ** Deallocate and destroy a parser.  Destructors are all called for
5182  ** all stack elements before shutting the parser down.
5183  **
5184 @@ -325,7 +325,7 @@
5185  ){
5186    int i;
5187    int stateno = pParser->yystack[pParser->yyidx].stateno;
5188
5189 +
5190    /* if( pParser->yyidx<0 ) return YY_NO_ACTION;  */
5191    i = yy_shift_ofst[stateno];
5192    if( i==YY_SHIFT_USE_DFLT ){
5193 @@ -369,7 +369,7 @@
5194  ){
5195    int i;
5196    int stateno = pParser->yystack[pParser->yyidx].stateno;
5197
5198 +
5199    i = yy_reduce_ofst[stateno];
5200    if( i==YY_REDUCE_USE_DFLT ){
5201      return yy_default[stateno];
5202 @@ -455,7 +455,7 @@
5203    ParseARG_FETCH;
5204    yymsp = &yypParser->yystack[yypParser->yyidx];
5205  #ifndef NDEBUG
5206 -  if( yyTraceFILE && yyruleno>=0 
5207 +  if( yyTraceFILE && yyruleno>=0
5208          && yyruleno<sizeof(yyRuleName)/sizeof(yyRuleName[0]) ){
5209      fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
5210        yyRuleName[yyruleno]);
5211 @@ -608,7 +608,7 @@
5212  #ifdef YYERRORSYMBOL
5213        /* A syntax error has occurred.
5214        ** The response to an error depends upon whether or not the
5215 -      ** grammar defines an error token "ERROR".  
5216 +      ** grammar defines an error token "ERROR".
5217        **
5218        ** This is what we do if the grammar does define ERROR:
5219        **
5220
5221 Property changes on: src/lempar.c
5222 ___________________________________________________________________
5223 Name: svn:eol-style
5224    + native
5225
5226 Index: src/connections.c
5227 ===================================================================
5228 --- src/connections.c   (.../tags/lighttpd-1.4.11)      (revision 1159)
5229 +++ src/connections.c   (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
5230 @@ -2,7 +2,6 @@
5231  
5232  #include <stdlib.h>
5233  #include <stdio.h>
5234 -#include <unistd.h>
5235  #include <errno.h>
5236  #include <string.h>
5237  #include <fcntl.h>
5238 @@ -26,8 +25,8 @@
5239  #include "inet_ntop_cache.h"
5240  
5241  #ifdef USE_OPENSSL
5242 -# include <openssl/ssl.h> 
5243 -# include <openssl/err.h> 
5244 +# include <openssl/ssl.h>
5245 +# include <openssl/err.h>
5246  #endif
5247  
5248  #ifdef HAVE_SYS_FILIO_H
5249 @@ -35,6 +34,7 @@
5250  #endif
5251  
5252  #include "sys-socket.h"
5253 +#include "sys-files.h"
5254  
5255  typedef struct {
5256                 PLUGIN_DATA;
5257 @@ -43,7 +43,7 @@
5258  static connection *connections_get_new_connection(server *srv) {
5259         connections *conns = srv->conns;
5260         size_t i;
5261 -       
5262 +
5263         if (conns->size == 0) {
5264                 conns->size = 128;
5265                 conns->ptr = NULL;
5266 @@ -54,21 +54,21 @@
5267         } else if (conns->size == conns->used) {
5268                 conns->size += 128;
5269                 conns->ptr = realloc(conns->ptr, sizeof(*conns->ptr) * conns->size);
5270 -               
5271 +
5272                 for (i = conns->used; i < conns->size; i++) {
5273                         conns->ptr[i] = connection_init(srv);
5274                 }
5275         }
5276  
5277         connection_reset(srv, conns->ptr[conns->used]);
5278 -#if 0  
5279 +#if 0
5280         fprintf(stderr, "%s.%d: add: ", __FILE__, __LINE__);
5281         for (i = 0; i < conns->used + 1; i++) {
5282                 fprintf(stderr, "%d ", conns->ptr[i]->fd);
5283         }
5284         fprintf(stderr, "\n");
5285 -#endif 
5286 -       
5287 +#endif
5288 +
5289         conns->ptr[conns->used]->ndx = conns->used;
5290         return conns->ptr[conns->used++];
5291  }
5292 @@ -77,26 +77,26 @@
5293         size_t i;
5294         connections *conns = srv->conns;
5295         connection *temp;
5296 -       
5297 +
5298         if (con == NULL) return -1;
5299 -       
5300 +
5301         if (-1 == con->ndx) return -1;
5302 -       
5303 +
5304         i = con->ndx;
5305 -       
5306 +
5307         /* not last element */
5308 -       
5309 +
5310         if (i != conns->used - 1) {
5311                 temp = conns->ptr[i];
5312                 conns->ptr[i] = conns->ptr[conns->used - 1];
5313                 conns->ptr[conns->used - 1] = temp;
5314 -               
5315 +
5316                 conns->ptr[i]->ndx = i;
5317                 conns->ptr[conns->used - 1]->ndx = -1;
5318         }
5319 -       
5320 +
5321         conns->used--;
5322 -       
5323 +
5324         con->ndx = -1;
5325  #if 0
5326         fprintf(stderr, "%s.%d: del: (%d)", __FILE__, __LINE__, conns->used);
5327 @@ -104,25 +104,23 @@
5328                 fprintf(stderr, "%d ", conns->ptr[i]->fd);
5329         }
5330         fprintf(stderr, "\n");
5331 -#endif 
5332 +#endif
5333         return 0;
5334  }
5335  
5336  int connection_close(server *srv, connection *con) {
5337  #ifdef USE_OPENSSL
5338         server_socket *srv_sock = con->srv_socket;
5339 -#endif
5340 -       
5341 -#ifdef USE_OPENSSL
5342 +
5343         if (srv_sock->is_ssl) {
5344                 if (con->ssl) SSL_free(con->ssl);
5345                 con->ssl = NULL;
5346         }
5347  #endif
5348 -       
5349 +
5350         fdevent_event_del(srv->ev, &(con->fde_ndx), con->fd);
5351         fdevent_unregister(srv->ev, con->fd);
5352 -#ifdef __WIN32
5353 +#ifdef _WIN32
5354         if (closesocket(con->fd)) {
5355                 log_error_write(srv, __FILE__, __LINE__, "sds",
5356                                 "(warning) close:", con->fd, strerror(errno));
5357 @@ -133,207 +131,96 @@
5358                                 "(warning) close:", con->fd, strerror(errno));
5359         }
5360  #endif
5361 -       
5362 +
5363         srv->cur_fds--;
5364  #if 0
5365         log_error_write(srv, __FILE__, __LINE__, "sd",
5366                         "closed()", con->fd);
5367  #endif
5368 -       
5369 +
5370         connection_del(srv, con);
5371         connection_set_state(srv, con, CON_STATE_CONNECT);
5372 -       
5373 +
5374         return 0;
5375  }
5376  
5377  #if 0
5378  static void dump_packet(const unsigned char *data, size_t len) {
5379         size_t i, j;
5380 -       
5381 +
5382         if (len == 0) return;
5383 -       
5384 +
5385         for (i = 0; i < len; i++) {
5386                 if (i % 16 == 0) fprintf(stderr, "  ");
5387 -               
5388 +
5389                 fprintf(stderr, "%02x ", data[i]);
5390 -               
5391 +
5392                 if ((i + 1) % 16 == 0) {
5393                         fprintf(stderr, "  ");
5394                         for (j = 0; j <= i % 16; j++) {
5395                                 unsigned char c;
5396 -                               
5397 +
5398                                 if (i-15+j >= len) break;
5399 -                               
5400 +
5401                                 c = data[i-15+j];
5402 -                               
5403 +
5404                                 fprintf(stderr, "%c", c > 32 && c < 128 ? c : '.');
5405                         }
5406 -                       
5407 +
5408                         fprintf(stderr, "\n");
5409                 }
5410         }
5411 -       
5412 +
5413         if (len % 16 != 0) {
5414                 for (j = i % 16; j < 16; j++) {
5415                         fprintf(stderr, "   ");
5416                 }
5417 -               
5418 +
5419                 fprintf(stderr, "  ");
5420                 for (j = i & ~0xf; j < len; j++) {
5421                         unsigned char c;
5422 -                       
5423 +
5424                         c = data[j];
5425                         fprintf(stderr, "%c", c > 32 && c < 128 ? c : '.');
5426                 }
5427                 fprintf(stderr, "\n");
5428         }
5429  }
5430 -#endif 
5431 -
5432 -static int connection_handle_read(server *srv, connection *con) {
5433 -       int len;
5434 -       buffer *b;
5435 -       int toread;
5436 -#ifdef USE_OPENSSL
5437 -       server_socket *srv_sock = con->srv_socket;
5438  #endif
5439  
5440 -       b = chunkqueue_get_append_buffer(con->read_queue);
5441 -       buffer_prepare_copy(b, 4096);
5442 +static network_status_t connection_handle_read(server *srv, connection *con) {
5443 +       off_t oldlen, newlen;
5444  
5445 -#ifdef USE_OPENSSL
5446 -       if (srv_sock->is_ssl) {
5447 -               len = SSL_read(con->ssl, b->ptr, b->size - 1);
5448 -       } else {
5449 -               if (ioctl(con->fd, FIONREAD, &toread)) {
5450 -                       log_error_write(srv, __FILE__, __LINE__, "sd", 
5451 -                                       "unexpected end-of-file:",
5452 -                                       con->fd);
5453 -                       return -1;
5454 -               }
5455 -               buffer_prepare_copy(b, toread);
5456 +    oldlen = chunkqueue_length(con->read_queue);
5457  
5458 -               len = read(con->fd, b->ptr, b->size - 1);
5459 -       }
5460 -#elif defined(__WIN32)
5461 -       len = recv(con->fd, b->ptr, b->size - 1, 0);
5462 -#else
5463 -       if (ioctl(con->fd, FIONREAD, &toread)) {
5464 -               log_error_write(srv, __FILE__, __LINE__, "sd", 
5465 -                               "unexpected end-of-file:",
5466 -                               con->fd);
5467 -               return -1;
5468 -       }
5469 -       buffer_prepare_copy(b, toread);
5470 +    switch(network_read_chunkqueue(srv, con, con->read_queue)) {
5471 +    case NETWORK_STATUS_SUCCESS:
5472 +        break;
5473 +    case NETWORK_STATUS_WAIT_FOR_EVENT:
5474 +        con->is_readable = 0;
5475 +        return NETWORK_STATUS_WAIT_FOR_EVENT;
5476 +    case NETWORK_STATUS_INTERRUPTED:
5477 +        con->is_readable = 1;
5478 +        return NETWORK_STATUS_WAIT_FOR_EVENT;
5479 +    case NETWORK_STATUS_CONNECTION_CLOSE:
5480 +        /* pipelining */
5481 +        con->is_readable = 0;
5482 +        return NETWORK_STATUS_CONNECTION_CLOSE;
5483 +    case NETWORK_STATUS_FATAL_ERROR:
5484 +        con->is_readable = 0;
5485  
5486 -       len = read(con->fd, b->ptr, b->size - 1);
5487 -#endif
5488 -       
5489 -       if (len < 0) {
5490 -               con->is_readable = 0;
5491 -               
5492 -#ifdef USE_OPENSSL
5493 -               if (srv_sock->is_ssl) {
5494 -                       int r, ssl_err;
5495 -                       
5496 -                       switch ((r = SSL_get_error(con->ssl, len))) {
5497 -                       case SSL_ERROR_WANT_READ:
5498 -                               return 0;
5499 -                       case SSL_ERROR_SYSCALL:
5500 -                               /**
5501 -                                * man SSL_get_error()
5502 -                                * 
5503 -                                * SSL_ERROR_SYSCALL
5504 -                                *   Some I/O error occurred.  The OpenSSL error queue may contain more 
5505 -                                *   information on the error.  If the error queue is empty (i.e.
5506 -                                *   ERR_get_error() returns 0), ret can be used to find out more about 
5507 -                                *   the error: If ret == 0, an EOF was observed that violates the
5508 -                                *   protocol.  If ret == -1, the underlying BIO reported an I/O error 
5509 -                                *   (for socket I/O on Unix systems, consult errno for details).
5510 -                                *
5511 -                                */
5512 -                               while((ssl_err = ERR_get_error())) {
5513 -                                       /* get all errors from the error-queue */
5514 -                                       log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:", 
5515 -                                                       r, ERR_error_string(ssl_err, NULL));
5516 -                               }
5517 +        connection_set_state(srv, con, CON_STATE_ERROR);
5518 +        return NETWORK_STATUS_FATAL_ERROR;
5519 +    default:
5520 +        SEGFAULT();
5521 +        break;
5522 +    }
5523  
5524 -                               switch(errno) {
5525 -                               default:
5526 -                                       log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:", 
5527 -                                                       len, r, errno,
5528 -                                                       strerror(errno));
5529 -                                       break;
5530 -                               }
5531 -                               
5532 -                               break;
5533 -                       case SSL_ERROR_ZERO_RETURN:
5534 -                               /* clean shutdown on the remote side */
5535 -                               
5536 -                               if (r == 0) {
5537 -                                       /* FIXME: later */
5538 -                               }
5539 -                               
5540 -                               /* fall thourgh */
5541 -                       default:
5542 -                               while((ssl_err = ERR_get_error())) {
5543 -                                       /* get all errors from the error-queue */
5544 -                                       log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:", 
5545 -                                                       r, ERR_error_string(ssl_err, NULL));
5546 -                               }
5547 -                               break;
5548 -                       }
5549 -               } else {
5550 -                       if (errno == EAGAIN) return 0;
5551 -                       if (errno == EINTR) {
5552 -                               /* we have been interrupted before we could read */
5553 -                               con->is_readable = 1;
5554 -                               return 0;
5555 -                       }
5556 -               
5557 -                       if (errno != ECONNRESET) {
5558 -                               /* expected for keep-alive */
5559 -                               log_error_write(srv, __FILE__, __LINE__, "ssd", "connection closed - read failed: ", strerror(errno), errno);
5560 -                       }
5561 -               }
5562 -#else
5563 -               if (errno == EAGAIN) return 0;
5564 -               if (errno == EINTR) {
5565 -                       /* we have been interrupted before we could read */
5566 -                       con->is_readable = 1;
5567 -                       return 0;
5568 -               }
5569 -               
5570 -               if (errno != ECONNRESET) {
5571 -                       /* expected for keep-alive */
5572 -                       log_error_write(srv, __FILE__, __LINE__, "ssd", "connection closed - read failed: ", strerror(errno), errno);
5573 -               }
5574 -#endif
5575 -               connection_set_state(srv, con, CON_STATE_ERROR);
5576 -               
5577 -               return -1;
5578 -       } else if (len == 0) {
5579 -               con->is_readable = 0;
5580 -               /* the other end close the connection -> KEEP-ALIVE */
5581 +    newlen = chunkqueue_length(con->read_queue);
5582  
5583 -               /* pipelining */
5584 +       con->bytes_read += (newlen - oldlen);
5585  
5586 -               return -2;
5587 -       } else if ((size_t)len < b->size - 1) {
5588 -               /* we got less then expected, wait for the next fd-event */
5589 -               
5590 -               con->is_readable = 0;
5591 -       }
5592 -       
5593 -       b->used = len;
5594 -       b->ptr[b->used++] = '\0';
5595 -       
5596 -       con->bytes_read += len;
5597 -#if 0
5598 -       dump_packet(b->ptr, len);
5599 -#endif
5600 -       
5601 -       return 0;
5602 +       return NETWORK_STATUS_SUCCESS;
5603  }
5604  
5605  static int connection_handle_write_prepare(server *srv, connection *con) {
5606 @@ -343,6 +230,7 @@
5607                 case HTTP_METHOD_GET:
5608                 case HTTP_METHOD_POST:
5609                 case HTTP_METHOD_HEAD:
5610 +                       /* webdav */
5611                 case HTTP_METHOD_PUT:
5612                 case HTTP_METHOD_MKCOL:
5613                 case HTTP_METHOD_DELETE:
5614 @@ -350,12 +238,14 @@
5615                 case HTTP_METHOD_MOVE:
5616                 case HTTP_METHOD_PROPFIND:
5617                 case HTTP_METHOD_PROPPATCH:
5618 +               case HTTP_METHOD_LOCK:
5619 +               case HTTP_METHOD_UNLOCK:
5620                         break;
5621                 case HTTP_METHOD_OPTIONS:
5622                         /*
5623                          * 400 is coming from the request-parser BEFORE uri.path is set
5624 -                        * 403 is from the response handler when noone else catched it 
5625 -                        * 
5626 +                        * 403 is from the response handler when noone else catched it
5627 +                        *
5628                          * */
5629                         if (con->uri.path->used &&
5630                             con->uri.path->ptr[0] != '*') {
5631 @@ -381,55 +271,58 @@
5632                         break;
5633                 }
5634         }
5635 -       
5636 +
5637         if (con->http_status == 0) {
5638                 con->http_status = 403;
5639         }
5640 -       
5641 +
5642         switch(con->http_status) {
5643         case 400: /* class: header + custom body */
5644         case 401:
5645         case 403:
5646         case 404:
5647         case 408:
5648 +       case 409:
5649 +       case 410:
5650         case 411:
5651         case 416:
5652         case 423:
5653         case 500:
5654         case 501:
5655         case 503:
5656 -       case 505: 
5657 +       case 505:
5658 +       case 509:
5659                 if (con->mode != DIRECT) break;
5660 -               
5661 +
5662                 con->file_finished = 0;
5663 -               
5664 +
5665                 buffer_reset(con->physical.path);
5666 -                               
5667 +
5668                 /* try to send static errorfile */
5669                 if (!buffer_is_empty(con->conf.errorfile_prefix)) {
5670                         stat_cache_entry *sce = NULL;
5671 -                       
5672 +
5673                         buffer_copy_string_buffer(con->physical.path, con->conf.errorfile_prefix);
5674                         buffer_append_string(con->physical.path, get_http_status_body_name(con->http_status));
5675 -                       
5676 +
5677                         if (HANDLER_ERROR != stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
5678                                 con->file_finished = 1;
5679 -                               
5680 +
5681                                 http_chunk_append_file(srv, con, con->physical.path, 0, sce->st.st_size);
5682                                 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type));
5683                         }
5684                 }
5685 -               
5686 -               if (!con->file_finished) {                      
5687 +
5688 +               if (!con->file_finished) {
5689                         buffer *b;
5690 -                       
5691 +
5692                         buffer_reset(con->physical.path);
5693 -                       
5694 +
5695                         con->file_finished = 1;
5696                         b = chunkqueue_get_append_buffer(con->write_queue);
5697 -                               
5698 +
5699                         /* build default error-page */
5700 -                       buffer_copy_string(b, 
5701 +                       buffer_copy_string(b,
5702                                            "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
5703                                            "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
5704                                            "         \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"
5705 @@ -439,7 +332,7 @@
5706                         buffer_append_long(b, con->http_status);
5707                         buffer_append_string(b, " - ");
5708                         buffer_append_string(b, get_http_status_name(con->http_status));
5709 -                       
5710 +
5711                         buffer_append_string(b,
5712                                              "</title>\n"
5713                                              " </head>\n"
5714 @@ -448,12 +341,12 @@
5715                         buffer_append_long(b, con->http_status);
5716                         buffer_append_string(b, " - ");
5717                         buffer_append_string(b, get_http_status_name(con->http_status));
5718 -                       
5719 -                       buffer_append_string(b,"</h1>\n" 
5720 +
5721 +                       buffer_append_string(b,"</h1>\n"
5722                                              " </body>\n"
5723                                              "</html>\n"
5724                                              );
5725 -                       
5726 +
5727                         response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
5728                 }
5729                 /* fall through */
5730 @@ -463,10 +356,10 @@
5731         case 301:
5732         case 302:
5733                 break;
5734 -               
5735 +
5736         case 206: /* write_queue is already prepared */
5737                 con->file_finished = 1;
5738 -               
5739 +
5740                 break;
5741         case 205: /* class: header only */
5742         case 304:
5743 @@ -474,19 +367,19 @@
5744                 /* disable chunked encoding again as we have no body */
5745                 con->response.transfer_encoding &= ~HTTP_TRANSFER_ENCODING_CHUNKED;
5746                 chunkqueue_reset(con->write_queue);
5747 -               
5748 +
5749                 con->file_finished = 1;
5750                 break;
5751         }
5752 -       
5753  
5754 +
5755         if (con->file_finished) {
5756 -               /* we have all the content and chunked encoding is not used, set a content-length */ 
5757 -               
5758 -               if ((!(con->parsed_response & HTTP_CONTENT_LENGTH)) && 
5759 +               /* we have all the content and chunked encoding is not used, set a content-length */
5760 +
5761 +               if ((!(con->parsed_response & HTTP_CONTENT_LENGTH)) &&
5762                     (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) == 0) {
5763                         buffer_copy_off_t(srv->tmp_buf, chunkqueue_length(con->write_queue));
5764 -               
5765 +
5766                         response_header_overwrite(srv, con, CONST_STR_LEN("Content-Length"), CONST_BUF_LEN(srv->tmp_buf));
5767                 }
5768         } else {
5769 @@ -495,74 +388,77 @@
5770                     ((con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) == 0)) {
5771                         con->keep_alive = 0;
5772                 }
5773 -               
5774 +
5775                 if (0 == (con->parsed_response & HTTP_CONNECTION)) {
5776                         /* (f)cgi did'nt send Connection: header
5777 -                        *                          
5778 +                        *
5779                          * shall we ?
5780                          */
5781                         if (((con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) == 0) &&
5782                             (con->parsed_response & HTTP_CONTENT_LENGTH) == 0) {
5783                                 /* without content_length, no keep-alive */
5784 -                               
5785 +
5786                                 con->keep_alive = 0;
5787                         }
5788                 } else {
5789                         /* a subrequest disable keep-alive although the client wanted it */
5790                         if (con->keep_alive && !con->response.keep_alive) {
5791                                 con->keep_alive = 0;
5792 -                               
5793 +
5794                                 /* FIXME: we have to drop the Connection: Header from the subrequest */
5795                         }
5796                 }
5797         }
5798 -       
5799 +
5800         if (con->request.http_method == HTTP_METHOD_HEAD) {
5801                 chunkqueue_reset(con->write_queue);
5802         }
5803  
5804         http_response_write_header(srv, con);
5805 -               
5806 +
5807         return 0;
5808  }
5809  
5810  static int connection_handle_write(server *srv, connection *con) {
5811 -       switch(network_write_chunkqueue(srv, con, con->write_queue)) {
5812 -       case 0:
5813 +    switch(network_write_chunkqueue(srv, con, con->write_queue)) {
5814 +       case NETWORK_STATUS_SUCCESS:
5815                 if (con->file_finished) {
5816                         connection_set_state(srv, con, CON_STATE_RESPONSE_END);
5817                         joblist_append(srv, con);
5818                 }
5819                 break;
5820 -       case -1: /* error on our side */
5821 +       case NETWORK_STATUS_FATAL_ERROR: /* error on our side */
5822                 log_error_write(srv, __FILE__, __LINE__, "sd",
5823                                 "connection closed: write failed on fd", con->fd);
5824                 connection_set_state(srv, con, CON_STATE_ERROR);
5825                 joblist_append(srv, con);
5826                 break;
5827 -       case -2: /* remote close */
5828 +       case NETWORK_STATUS_CONNECTION_CLOSE: /* remote close */
5829                 connection_set_state(srv, con, CON_STATE_ERROR);
5830                 joblist_append(srv, con);
5831                 break;
5832 -       case 1:
5833 +       case NETWORK_STATUS_WAIT_FOR_EVENT:
5834                 con->is_writable = 0;
5835 -               
5836 +
5837                 /* not finished yet -> WRITE */
5838                 break;
5839 +       case NETWORK_STATUS_INTERRUPTED:
5840 +               con->is_writable = 1;
5841 +               break;
5842 +       case NETWORK_STATUS_UNSET:
5843 +               break;
5844         }
5845 -       
5846 +
5847         return 0;
5848  }
5849  
5850 -
5851 -
5852  connection *connection_init(server *srv) {
5853         connection *con;
5854 -       
5855 +
5856         UNUSED(srv);
5857  
5858         con = calloc(1, sizeof(*con));
5859 -               
5860 +
5861         con->fd = 0;
5862         con->ndx = -1;
5863         con->fde_ndx = -1;
5864 @@ -573,32 +469,32 @@
5865  
5866  #define CLEAN(x) \
5867         con->x = buffer_init();
5868 -       
5869 +
5870         CLEAN(request.uri);
5871         CLEAN(request.request_line);
5872         CLEAN(request.request);
5873         CLEAN(request.pathinfo);
5874 -       
5875 +
5876         CLEAN(request.orig_uri);
5877 -       
5878 +
5879         CLEAN(uri.scheme);
5880         CLEAN(uri.authority);
5881         CLEAN(uri.path);
5882         CLEAN(uri.path_raw);
5883         CLEAN(uri.query);
5884 -       
5885 +
5886         CLEAN(physical.doc_root);
5887         CLEAN(physical.path);
5888         CLEAN(physical.basedir);
5889         CLEAN(physical.rel_path);
5890         CLEAN(physical.etag);
5891         CLEAN(parse_request);
5892 -       
5893 +
5894         CLEAN(authed_user);
5895         CLEAN(server_name);
5896         CLEAN(error_handler);
5897         CLEAN(dst_addr_buf);
5898 -       
5899 +
5900  #undef CLEAN
5901         con->write_queue = chunkqueue_init();
5902         con->read_queue = chunkqueue_init();
5903 @@ -608,26 +504,26 @@
5904         con->request.headers      = array_init();
5905         con->response.headers     = array_init();
5906         con->environment     = array_init();
5907 -       
5908 +
5909         /* init plugin specific connection structures */
5910 -       
5911 +
5912         con->plugin_ctx = calloc(1, (srv->plugins.used + 1) * sizeof(void *));
5913 -       
5914 +
5915         con->cond_cache = calloc(srv->config_context->used, sizeof(cond_cache_t));
5916         config_setup_connection(srv, con);
5917 -       
5918 +
5919         return con;
5920  }
5921  
5922  void connections_free(server *srv) {
5923         connections *conns = srv->conns;
5924 -       size_t i;       
5925 -       
5926 +       size_t i;
5927 +
5928         for (i = 0; i < conns->size; i++) {
5929                 connection *con = conns->ptr[i];
5930 -               
5931 +
5932                 connection_reset(srv, con);
5933 -               
5934 +
5935                 chunkqueue_free(con->write_queue);
5936                 chunkqueue_free(con->read_queue);
5937                 chunkqueue_free(con->request_content_queue);
5938 @@ -637,27 +533,27 @@
5939  
5940  #define CLEAN(x) \
5941         buffer_free(con->x);
5942 -               
5943 +
5944                 CLEAN(request.uri);
5945                 CLEAN(request.request_line);
5946                 CLEAN(request.request);
5947                 CLEAN(request.pathinfo);
5948 -               
5949 +
5950                 CLEAN(request.orig_uri);
5951 -               
5952 +
5953                 CLEAN(uri.scheme);
5954                 CLEAN(uri.authority);
5955                 CLEAN(uri.path);
5956                 CLEAN(uri.path_raw);
5957                 CLEAN(uri.query);
5958 -               
5959 +
5960                 CLEAN(physical.doc_root);
5961                 CLEAN(physical.path);
5962                 CLEAN(physical.basedir);
5963                 CLEAN(physical.etag);
5964                 CLEAN(physical.rel_path);
5965                 CLEAN(parse_request);
5966 -               
5967 +
5968                 CLEAN(authed_user);
5969                 CLEAN(server_name);
5970                 CLEAN(error_handler);
5971 @@ -665,97 +561,97 @@
5972  #undef CLEAN
5973                 free(con->plugin_ctx);
5974                 free(con->cond_cache);
5975 -               
5976 +
5977                 free(con);
5978         }
5979 -       
5980 +
5981         free(conns->ptr);
5982  }
5983  
5984  
5985  int connection_reset(server *srv, connection *con) {
5986         size_t i;
5987 -       
5988 +
5989         plugins_call_connection_reset(srv, con);
5990 -       
5991 +
5992         con->is_readable = 1;
5993         con->is_writable = 1;
5994         con->http_status = 0;
5995         con->file_finished = 0;
5996         con->file_started = 0;
5997         con->got_response = 0;
5998 -       
5999 +
6000         con->parsed_response = 0;
6001 -       
6002 +
6003         con->bytes_written = 0;
6004         con->bytes_written_cur_second = 0;
6005         con->bytes_read = 0;
6006         con->bytes_header = 0;
6007         con->loops_per_request = 0;
6008 -       
6009 +
6010         con->request.http_method = HTTP_METHOD_UNSET;
6011         con->request.http_version = HTTP_VERSION_UNSET;
6012 -       
6013 +
6014         con->request.http_if_modified_since = NULL;
6015         con->request.http_if_none_match = NULL;
6016 -       
6017 +
6018         con->response.keep_alive = 0;
6019         con->response.content_length = -1;
6020         con->response.transfer_encoding = 0;
6021 -       
6022 +
6023         con->mode = DIRECT;
6024 -       
6025 +
6026  #define CLEAN(x) \
6027         if (con->x) buffer_reset(con->x);
6028 -       
6029 +
6030         CLEAN(request.uri);
6031         CLEAN(request.request_line);
6032         CLEAN(request.pathinfo);
6033         CLEAN(request.request);
6034 -       
6035 +
6036         CLEAN(request.orig_uri);
6037 -       
6038 +
6039         CLEAN(uri.scheme);
6040         CLEAN(uri.authority);
6041         CLEAN(uri.path);
6042         CLEAN(uri.path_raw);
6043         CLEAN(uri.query);
6044 -       
6045 +
6046         CLEAN(physical.doc_root);
6047         CLEAN(physical.path);
6048         CLEAN(physical.basedir);
6049         CLEAN(physical.rel_path);
6050         CLEAN(physical.etag);
6051 -       
6052 +
6053         CLEAN(parse_request);
6054 -       
6055 +
6056         CLEAN(authed_user);
6057         CLEAN(server_name);
6058         CLEAN(error_handler);
6059 -#undef CLEAN   
6060 -       
6061 +#undef CLEAN
6062 +
6063  #define CLEAN(x) \
6064 -       if (con->x) con->x->used = 0;   
6065 -       
6066 +       if (con->x) con->x->used = 0;
6067 +
6068  #undef CLEAN
6069 -       
6070 +
6071  #define CLEAN(x) \
6072                 con->request.x = NULL;
6073 -       
6074 +
6075         CLEAN(http_host);
6076         CLEAN(http_range);
6077         CLEAN(http_content_type);
6078  #undef CLEAN
6079         con->request.content_length = 0;
6080 -       
6081 +
6082         array_reset(con->request.headers);
6083         array_reset(con->response.headers);
6084         array_reset(con->environment);
6085 -       
6086 +
6087         chunkqueue_reset(con->write_queue);
6088         chunkqueue_reset(con->request_content_queue);
6089  
6090 -       /* the plugins should cleanup themself */       
6091 +       /* the plugins should cleanup themself */
6092         for (i = 0; i < srv->plugins.used; i++) {
6093                 plugin *p = ((plugin **)(srv->plugins.ptr))[i];
6094                 plugin_data *pd = p->data;
6095 @@ -768,7 +664,7 @@
6096  
6097                 con->plugin_ctx[pd->id] = NULL;
6098         }
6099 -       
6100 +
6101  #if COND_RESULT_UNSET
6102         for (i = srv->config_context->used - 1; i >= 0; i --) {
6103                 con->cond_cache[i].result = COND_RESULT_UNSET;
6104 @@ -777,56 +673,56 @@
6105  #else
6106         memset(con->cond_cache, 0, sizeof(cond_cache_t) * srv->config_context->used);
6107  #endif
6108 -       
6109 +
6110         con->header_len = 0;
6111         con->in_error_handler = 0;
6112 -       
6113 +
6114         config_setup_connection(srv, con);
6115 -       
6116 +
6117         return 0;
6118  }
6119  
6120  /**
6121 - * 
6122 - * search for \r\n\r\n 
6123 - * 
6124 + *
6125 + * search for \r\n\r\n
6126 + *
6127   * this is a special 32bit version which is using a sliding window for
6128 - * the comparisions 
6129 - * 
6130 + * the comparisions
6131 + *
6132   * how it works:
6133 - * 
6134 + *
6135   * b:      'abcdefg'
6136   * rnrn:   'cdef'
6137 - * 
6138 + *
6139   * cmpbuf: abcd != cdef
6140   * cmpbuf: bcde != cdef
6141   * cmpbuf: cdef == cdef -> return &c
6142 - * 
6143 - * cmpbuf and rnrn are treated as 32bit uint and bit-ops are used to 
6144 + *
6145 + * cmpbuf and rnrn are treated as 32bit uint and bit-ops are used to
6146   * maintain cmpbuf and rnrn
6147 - * 
6148 + *
6149   */
6150  
6151  char *buffer_search_rnrn(buffer *b) {
6152         uint32_t cmpbuf, rnrn;
6153         char *cp;
6154         size_t i;
6155 -       
6156 +
6157         if (b->used < 4) return NULL;
6158 -       
6159 +
6160         rnrn = ('\r' << 24) | ('\n' << 16) |
6161                 ('\r' << 8) | ('\n' << 0);
6162 -       
6163 +
6164         cmpbuf = (b->ptr[0] << 24) | (b->ptr[1] << 16) |
6165                 (b->ptr[2] << 8) | (b->ptr[3] << 0);
6166 -               
6167 +
6168         cp = b->ptr + 4;
6169         for (i = 0; i < b->used - 4; i++) {
6170                 if (cmpbuf == rnrn) return cp - 4;
6171 -                       
6172 +
6173                 cmpbuf = (cmpbuf << 8 | *(cp++)) & 0xffffffff;
6174         }
6175 -       
6176 +
6177         return NULL;
6178  }
6179  /**
6180 @@ -840,22 +736,25 @@
6181         chunk *c;
6182         chunkqueue *cq = con->read_queue;
6183         chunkqueue *dst_cq = con->request_content_queue;
6184 -       
6185 +
6186         if (con->is_readable) {
6187                 con->read_idle_ts = srv->cur_ts;
6188 -       
6189 +
6190                 switch(connection_handle_read(srv, con)) {
6191 -               case -1:
6192 +               case NETWORK_STATUS_FATAL_ERROR:
6193                         return -1;
6194 -               case -2:
6195 +               case NETWORK_STATUS_CONNECTION_CLOSE:
6196                         /* remote side closed the connection
6197                          * if we still have content, handle it, if not leave here */
6198  
6199                         if (cq->first == cq->last &&
6200 -                           cq->first->mem->used == 0) {
6201 +                (NULL == cq->first ||
6202 +                           cq->first->mem->used == 0)) {
6203  
6204                                 /* conn-closed, leave here */
6205                                 connection_set_state(srv, con, CON_STATE_ERROR);
6206 +
6207 +                return 0;
6208                         }
6209                 default:
6210                         break;
6211 @@ -891,14 +790,14 @@
6212                         /* the last node was empty */
6213                         if (c->next == NULL) {
6214                                 cq->last = c;
6215 -                       } 
6216 +                       }
6217  
6218                         c = c->next;
6219                 } else {
6220                         c = c->next;
6221                 }
6222         }
6223 -       
6224 +
6225         /* nothing to handle */
6226         if (cq->first == NULL) return 0;
6227  
6228 @@ -906,25 +805,26 @@
6229         case CON_STATE_READ:
6230                 /* prepare con->request.request */
6231                 c = cq->first;
6232 -               
6233 +
6234                 /* check if we need the full package */
6235                 if (con->request.request->used == 0) {
6236                         buffer b;
6237 -                       
6238 +
6239                         b.ptr = c->mem->ptr + c->offset;
6240                         b.used = c->mem->used - c->offset;
6241 -                       
6242 +
6243                         if (NULL != (h_term = buffer_search_rnrn(&b))) {
6244                                 /* \r\n\r\n found
6245                                  * - copy everything incl. the terminator to request.request
6246                                  */
6247 -                               
6248 -                               buffer_copy_string_len(con->request.request, 
6249 -                                                      b.ptr, 
6250 +
6251 +                               buffer_copy_string_len(con->request.request,
6252 +                                                      b.ptr,
6253                                                        h_term - b.ptr + 4);
6254 -                               
6255 +
6256                                 /* the buffer has been read up to the terminator */
6257                                 c->offset += h_term - b.ptr + 4;
6258 +
6259                         } else {
6260                                 /* not found, copy everything */
6261                                 buffer_copy_string_len(con->request.request, c->mem->ptr + c->offset, c->mem->used - c->offset - 1);
6262 @@ -932,14 +832,14 @@
6263                         }
6264                 } else {
6265                         /* have to take care of overlapping header terminators */
6266 -                       
6267 +
6268                         size_t l = con->request.request->used - 2;
6269                         char *s  = con->request.request->ptr;
6270                         buffer b;
6271 -                       
6272 +
6273                         b.ptr = c->mem->ptr + c->offset;
6274                         b.used = c->mem->used - c->offset;
6275 -                       
6276 +
6277                         if (con->request.request->used - 1 > 3 &&
6278                             c->mem->used > 1 &&
6279                             s[l-2] == '\r' &&
6280 @@ -948,7 +848,7 @@
6281                             c->mem->ptr[0] == '\n') {
6282                                 buffer_append_string_len(con->request.request, c->mem->ptr + c->offset, 1);
6283                                 c->offset += 1;
6284 -                               
6285 +
6286                                 h_term = con->request.request->ptr;
6287                         } else if (con->request.request->used - 1 > 2 &&
6288                                    c->mem->used > 2 &&
6289 @@ -958,7 +858,7 @@
6290                                    c->mem->ptr[1] == '\n') {
6291                                 buffer_append_string_len(con->request.request, c->mem->ptr + c->offset, 2);
6292                                 c->offset += 2;
6293 -                               
6294 +
6295                                 h_term = con->request.request->ptr;
6296                         } else if (con->request.request->used - 1 > 1 &&
6297                                    c->mem->used > 3 &&
6298 @@ -968,17 +868,17 @@
6299                                    c->mem->ptr[2] == '\n') {
6300                                 buffer_append_string_len(con->request.request, c->mem->ptr + c->offset, 3);
6301                                 c->offset += 3;
6302 -                               
6303 +
6304                                 h_term = con->request.request->ptr;
6305                         } else if (NULL != (h_term = buffer_search_string_len(&b, "\r\n\r\n", 4))) {
6306                                 /* \r\n\r\n found
6307                                  * - copy everything incl. the terminator to request.request
6308                                  */
6309 -                               
6310 -                               buffer_append_string_len(con->request.request, 
6311 -                                                      c->mem->ptr + c->offset, 
6312 +
6313 +                               buffer_append_string_len(con->request.request,
6314 +                                                      c->mem->ptr + c->offset,
6315                                                        c->offset + h_term - b.ptr + 4);
6316 -                               
6317 +
6318                                 /* the buffer has been read up to the terminator */
6319                                 c->offset += h_term - b.ptr + 4;
6320                         } else {
6321 @@ -999,16 +899,16 @@
6322                         connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
6323                 }
6324                 break;
6325 -       case CON_STATE_READ_POST: 
6326 +       case CON_STATE_READ_POST:
6327                 for (c = cq->first; c && (dst_cq->bytes_in != (off_t)con->request.content_length); c = c->next) {
6328                         off_t weWant, weHave, toRead;
6329 -                       
6330 +
6331                         weWant = con->request.content_length - dst_cq->bytes_in;
6332 -                       
6333 +
6334                         assert(c->mem->used);
6335 -                       
6336 +
6337                         weHave = c->mem->used - c->offset - 1;
6338 -                               
6339 +
6340                         toRead = weHave > weWant ? weWant : weHave;
6341  
6342                         /* the new way, copy everything into a chunkqueue whcih might use tempfiles */
6343 @@ -1017,13 +917,13 @@
6344                                 /* copy everything to max 1Mb sized tempfiles */
6345  
6346                                 /*
6347 -                                * if the last chunk is 
6348 +                                * if the last chunk is
6349                                  * - smaller than 1Mb (size < 1Mb)
6350                                  * - not read yet (offset == 0)
6351                                  * -> append to it
6352                                  * otherwise
6353 -                                * -> create a new chunk 
6354 -                                * 
6355 +                                * -> create a new chunk
6356 +                                *
6357                                  * */
6358  
6359                                 if (dst_cq->last &&
6360 @@ -1056,14 +956,14 @@
6361                                 /* we have a chunk, let's write to it */
6362  
6363                                 if (dst_c->file.fd == -1) {
6364 -                                       /* we don't have file to write to, 
6365 +                                       /* we don't have file to write to,
6366                                          * EACCES might be one reason.
6367                                          *
6368                                          * Instead of sending 500 we send 413 and say the request is too large
6369                                          *  */
6370  
6371                                         log_error_write(srv, __FILE__, __LINE__, "sbs",
6372 -                                                       "denying upload as opening to temp-file for upload failed:", 
6373 +                                                       "denying upload as opening to temp-file for upload failed:",
6374                                                         dst_c->file.name, strerror(errno));
6375  
6376                                         con->http_status = 413; /* Request-Entity too large */
6377 @@ -1074,15 +974,15 @@
6378                                 }
6379  
6380                                 if (toRead != write(dst_c->file.fd, c->mem->ptr + c->offset, toRead)) {
6381 -                                       /* write failed for some reason ... disk full ? */ 
6382 +                                       /* write failed for some reason ... disk full ? */
6383                                         log_error_write(srv, __FILE__, __LINE__, "sbs",
6384 -                                                       "denying upload as writing to file failed:", 
6385 +                                                       "denying upload as writing to file failed:",
6386                                                         dst_c->file.name, strerror(errno));
6387 -                                       
6388 +
6389                                         con->http_status = 413; /* Request-Entity too large */
6390                                         con->keep_alive = 0;
6391                                         connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
6392 -                               
6393 +
6394                                         close(dst_c->file.fd);
6395                                         dst_c->file.fd = -1;
6396  
6397 @@ -1090,7 +990,7 @@
6398                                 }
6399  
6400                                 dst_c->file.length += toRead;
6401 -                                       
6402 +
6403                                 if (dst_cq->bytes_in + toRead == (off_t)con->request.content_length) {
6404                                         /* we read everything, close the chunk */
6405                                         close(dst_c->file.fd);
6406 @@ -1102,7 +1002,7 @@
6407                                 b = chunkqueue_get_append_buffer(dst_cq);
6408                                 buffer_copy_string_len(b, c->mem->ptr + c->offset, toRead);
6409                         }
6410 -                       
6411 +
6412                         c->offset += toRead;
6413                         dst_cq->bytes_in += toRead;
6414                 }
6415 @@ -1111,7 +1011,7 @@
6416                 if (dst_cq->bytes_in == (off_t)con->request.content_length) {
6417                         connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
6418                 }
6419 -                       
6420 +
6421                 break;
6422         }
6423  
6424 @@ -1123,9 +1023,9 @@
6425  handler_t connection_handle_fdevent(void *s, void *context, int revents) {
6426         server     *srv = (server *)s;
6427         connection *con = context;
6428 -       
6429 +
6430         joblist_append(srv, con);
6431 -       
6432 +
6433         if (revents & FDEVENT_IN) {
6434                 con->is_readable = 1;
6435  #if 0
6436 @@ -1136,19 +1036,19 @@
6437                 con->is_writable = 1;
6438                 /* we don't need the event twice */
6439         }
6440 -       
6441 -       
6442 +
6443 +
6444         if (revents & ~(FDEVENT_IN | FDEVENT_OUT)) {
6445                 /* looks like an error */
6446 -                                               
6447 +
6448                 /* FIXME: revents = 0x19 still means that we should read from the queue */
6449                 if (revents & FDEVENT_HUP) {
6450                         if (con->state == CON_STATE_CLOSE) {
6451                                 con->close_timeout_ts = 0;
6452                         } else {
6453                                 /* sigio reports the wrong event here
6454 -                                * 
6455 -                                * there was no HUP at all 
6456 +                                *
6457 +                                * there was no HUP at all
6458                                  */
6459  #ifdef USE_LINUX_SIGIO
6460                                 if (srv->ev->in_sigio == 1) {
6461 @@ -1160,32 +1060,39 @@
6462  #else
6463                                 connection_set_state(srv, con, CON_STATE_ERROR);
6464  #endif
6465 -                               
6466 +
6467                         }
6468                 } else if (revents & FDEVENT_ERR) {
6469  #ifndef USE_LINUX_SIGIO
6470                         log_error_write(srv, __FILE__, __LINE__, "sd",
6471                                         "connection closed: poll() -> ERR", con->fd);
6472 -#endif 
6473 +#endif
6474                         connection_set_state(srv, con, CON_STATE_ERROR);
6475                 } else {
6476                         log_error_write(srv, __FILE__, __LINE__, "sd",
6477                                         "connection closed: poll() -> ???", revents);
6478 -               } 
6479 +               }
6480         }
6481 -       
6482 +
6483         if (con->state == CON_STATE_READ ||
6484             con->state == CON_STATE_READ_POST) {
6485                 connection_handle_read_state(srv, con);
6486 +               /**
6487 +                * if SSL_read() is not readin in the full packet we won't get
6488 +                * a fdevent as the low-level has already fetched everything.
6489 +                *
6490 +                * we have to call the state-engine to read the rest of the packet
6491 +                */
6492 +               if (con->is_readable) joblist_append(srv, con);
6493         }
6494 -       
6495 +
6496         if (con->state == CON_STATE_WRITE &&
6497             !chunkqueue_is_empty(con->write_queue) &&
6498             con->is_writable) {
6499 -               
6500 +
6501                 if (-1 == connection_handle_write(srv, con)) {
6502                         connection_set_state(srv, con, CON_STATE_ERROR);
6503 -                       
6504 +
6505                         log_error_write(srv, __FILE__, __LINE__, "ds",
6506                                         con->fd,
6507                                         "handle write failed.");
6508 @@ -1193,30 +1100,30 @@
6509                         con->write_request_ts = srv->cur_ts;
6510                 }
6511         }
6512 -       
6513 +
6514         if (con->state == CON_STATE_CLOSE) {
6515                 /* flush the read buffers */
6516                 int b;
6517 -               
6518 +
6519                 if (ioctl(con->fd, FIONREAD, &b)) {
6520                         log_error_write(srv, __FILE__, __LINE__, "ss",
6521                                         "ioctl() failed", strerror(errno));
6522                 }
6523 -               
6524 +
6525                 if (b > 0) {
6526                         char buf[1024];
6527                         log_error_write(srv, __FILE__, __LINE__, "sdd",
6528                                         "CLOSE-read()", con->fd, b);
6529 -                       
6530 +
6531                         /* */
6532                         read(con->fd, buf, sizeof(buf));
6533                 } else {
6534                         /* nothing to read */
6535 -                       
6536 +
6537                         con->close_timeout_ts = 0;
6538                 }
6539         }
6540 -       
6541 +
6542         return HANDLER_FINISHED;
6543  }
6544  
6545 @@ -1229,63 +1136,68 @@
6546         sock_addr cnt_addr;
6547         socklen_t cnt_len;
6548         /* accept it and register the fd */
6549 -       
6550 +
6551         cnt_len = sizeof(cnt_addr);
6552  
6553         if (-1 == (cnt = accept(srv_socket->fd, (struct sockaddr *) &cnt_addr, &cnt_len))) {
6554 +#ifdef _WIN32
6555 +        errno = WSAGetLastError();
6556 +#endif
6557                 if ((errno != EAGAIN) &&
6558 +            (errno != EWOULDBLOCK) &&
6559                     (errno != EINTR)) {
6560 -                       log_error_write(srv, __FILE__, __LINE__, "ssd", "accept failed:", strerror(errno), errno);
6561 +                       log_error_write(srv, __FILE__, __LINE__, "ssd", "accept failed:", strerror(errno), srv_socket->fd);
6562                 }
6563                 return NULL;
6564         } else {
6565                 connection *con;
6566 -               
6567 +
6568                 srv->cur_fds++;
6569 -               
6570 +
6571                 /* ok, we have the connection, register it */
6572  #if 0
6573                 log_error_write(srv, __FILE__, __LINE__, "sd",
6574                                 "appected()", cnt);
6575  #endif
6576                 srv->con_opened++;
6577 -               
6578 +
6579                 con = connections_get_new_connection(srv);
6580 -               
6581                 con->fd = cnt;
6582                 con->fde_ndx = -1;
6583 -#if 0          
6584 +#if 0
6585                 gettimeofday(&(con->start_tv), NULL);
6586 -#endif         
6587 +#endif
6588                 fdevent_register(srv->ev, con->fd, connection_handle_fdevent, con);
6589 -               
6590 +
6591                 connection_set_state(srv, con, CON_STATE_REQUEST_START);
6592 -               
6593 +
6594                 con->connection_start = srv->cur_ts;
6595                 con->dst_addr = cnt_addr;
6596                 buffer_copy_string(con->dst_addr_buf, inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
6597                 con->srv_socket = srv_socket;
6598 -               
6599 +
6600                 if (-1 == (fdevent_fcntl_set(srv->ev, con->fd))) {
6601                         log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed: ", strerror(errno));
6602 +                       connection_close(srv, con);
6603                         return NULL;
6604                 }
6605  #ifdef USE_OPENSSL
6606                 /* connect FD to SSL */
6607                 if (srv_socket->is_ssl) {
6608                         if (NULL == (con->ssl = SSL_new(srv_socket->ssl_ctx))) {
6609 -                               log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
6610 +                               log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
6611                                                 ERR_error_string(ERR_get_error(), NULL));
6612 -                               
6613 +                               connection_close(srv, con);
6614                                 return NULL;
6615                         }
6616 -                       
6617 +
6618                         SSL_set_accept_state(con->ssl);
6619                         con->conf.is_ssl=1;
6620 -                       
6621 +
6622                         if (1 != (SSL_set_fd(con->ssl, cnt))) {
6623 -                               log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
6624 +                               log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
6625                                                 ERR_error_string(ERR_get_error(), NULL));
6626 +                               connection_close(srv, con);
6627                                 return NULL;
6628                         }
6629                 }
6630 @@ -1300,10 +1212,10 @@
6631  #ifdef USE_OPENSSL
6632         server_socket *srv_sock = con->srv_socket;
6633  #endif
6634 -       
6635 +
6636         if (srv->srvconf.log_state_handling) {
6637 -               log_error_write(srv, __FILE__, __LINE__, "sds", 
6638 -                               "state at start", 
6639 +               log_error_write(srv, __FILE__, __LINE__, "sds",
6640 +                               "state at start",
6641                                 con->fd,
6642                                 connection_get_state(con->state));
6643         }
6644 @@ -1311,91 +1223,91 @@
6645         while (done == 0) {
6646                 size_t ostate = con->state;
6647                 int b;
6648 -               
6649 +
6650                 switch (con->state) {
6651                 case CON_STATE_REQUEST_START: /* transient */
6652                         if (srv->srvconf.log_state_handling) {
6653 -                               log_error_write(srv, __FILE__, __LINE__, "sds", 
6654 +                               log_error_write(srv, __FILE__, __LINE__, "sds",
6655                                                 "state for fd", con->fd, connection_get_state(con->state));
6656                         }
6657 -                       
6658 +
6659                         con->request_start = srv->cur_ts;
6660                         con->read_idle_ts = srv->cur_ts;
6661 -                       
6662 +
6663                         con->request_count++;
6664                         con->loops_per_request = 0;
6665 -                       
6666 +
6667                         connection_set_state(srv, con, CON_STATE_READ);
6668 -                       
6669 +
6670                         break;
6671                 case CON_STATE_REQUEST_END: /* transient */
6672                         if (srv->srvconf.log_state_handling) {
6673 -                               log_error_write(srv, __FILE__, __LINE__, "sds", 
6674 +                               log_error_write(srv, __FILE__, __LINE__, "sds",
6675                                                 "state for fd", con->fd, connection_get_state(con->state));
6676                         }
6677 -                       
6678 +
6679                         if (http_request_parse(srv, con)) {
6680                                 /* we have to read some data from the POST request */
6681 -                               
6682 +
6683                                 connection_set_state(srv, con, CON_STATE_READ_POST);
6684  
6685                                 break;
6686                         }
6687 -                       
6688 +
6689                         connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
6690 -                       
6691 +
6692                         break;
6693                 case CON_STATE_HANDLE_REQUEST:
6694 -                       /* 
6695 +                       /*
6696                          * the request is parsed
6697 -                        * 
6698 +                        *
6699                          * decided what to do with the request
6700 -                        * - 
6701 -                        * 
6702 -                        * 
6703 +                        * -
6704 +                        *
6705 +                        *
6706                          */
6707 -                       
6708 +
6709                         if (srv->srvconf.log_state_handling) {
6710 -                               log_error_write(srv, __FILE__, __LINE__, "sds", 
6711 +                               log_error_write(srv, __FILE__, __LINE__, "sds",
6712                                                 "state for fd", con->fd, connection_get_state(con->state));
6713                         }
6714 -                       
6715 +
6716                         switch (r = http_response_prepare(srv, con)) {
6717                         case HANDLER_FINISHED:
6718                                 if (con->http_status == 404 ||
6719                                     con->http_status == 403) {
6720                                         /* 404 error-handler */
6721 -                                       
6722 -                                       if (con->in_error_handler == 0 && 
6723 +
6724 +                                       if (con->in_error_handler == 0 &&
6725                                             (!buffer_is_empty(con->conf.error_handler) ||
6726                                              !buffer_is_empty(con->error_handler))) {
6727                                                 /* call error-handler */
6728 -                                               
6729 +
6730                                                 con->error_handler_saved_status = con->http_status;
6731                                                 con->http_status = 0;
6732 -                                               
6733 +
6734                                                 if (buffer_is_empty(con->error_handler)) {
6735                                                         buffer_copy_string_buffer(con->request.uri, con->conf.error_handler);
6736                                                 } else {
6737                                                         buffer_copy_string_buffer(con->request.uri, con->error_handler);
6738                                                 }
6739                                                 buffer_reset(con->physical.path);
6740 -                                               
6741 +
6742                                                 con->in_error_handler = 1;
6743 -                                               
6744 +
6745                                                 connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
6746 -                                               
6747 +
6748                                                 done = -1;
6749                                                 break;
6750                                         } else if (con->in_error_handler) {
6751                                                 /* error-handler is a 404 */
6752 -                                               
6753 +
6754                                                 /* continue as normal, status is the same */
6755 -                                               log_error_write(srv, __FILE__, __LINE__, "sb", 
6756 +                                               log_error_write(srv, __FILE__, __LINE__, "sb",
6757                                                                 "Warning: Either the error-handler returned status 404 or the error-handler itself was not found:", con->request.uri);
6758 -                                               log_error_write(srv, __FILE__, __LINE__, "sd", 
6759 +                                               log_error_write(srv, __FILE__, __LINE__, "sd",
6760                                                                 "returning the original status", con->error_handler_saved_status);
6761 -                                               log_error_write(srv, __FILE__, __LINE__, "s", 
6762 +                                               log_error_write(srv, __FILE__, __LINE__, "s",
6763                                                                 "If this is a rails app: check your production.log");
6764                                                 con->http_status = con->error_handler_saved_status;
6765                                         }
6766 @@ -1403,26 +1315,26 @@
6767                                         /* error-handler is back and has generated content */
6768                                         /* if Status: was set, take it otherwise use 200 */
6769                                 }
6770 -                               
6771 +
6772                                 if (con->http_status == 0) con->http_status = 200;
6773 -                               
6774 +
6775                                 /* we have something to send, go on */
6776                                 connection_set_state(srv, con, CON_STATE_RESPONSE_START);
6777                                 break;
6778                         case HANDLER_WAIT_FOR_FD:
6779                                 srv->want_fds++;
6780 -                               
6781 +
6782                                 fdwaitqueue_append(srv, con);
6783 -                               
6784 +
6785                                 connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
6786 -                               
6787 +
6788                                 break;
6789                         case HANDLER_COMEBACK:
6790                                 done = -1;
6791                         case HANDLER_WAIT_FOR_EVENT:
6792                                 /* come back here */
6793                                 connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
6794 -                               
6795 +
6796                                 break;
6797                         case HANDLER_ERROR:
6798                                 /* something went wrong */
6799 @@ -1432,44 +1344,44 @@
6800                                 log_error_write(srv, __FILE__, __LINE__, "sdd", "unknown ret-value: ", con->fd, r);
6801                                 break;
6802                         }
6803 -                       
6804 +
6805                         break;
6806                 case CON_STATE_RESPONSE_START:
6807 -                       /* 
6808 +                       /*
6809                          * the decision is done
6810                          * - create the HTTP-Response-Header
6811 -                        * 
6812 +                        *
6813                          */
6814 -                       
6815 +
6816                         if (srv->srvconf.log_state_handling) {
6817 -                               log_error_write(srv, __FILE__, __LINE__, "sds", 
6818 +                               log_error_write(srv, __FILE__, __LINE__, "sds",
6819                                                 "state for fd", con->fd, connection_get_state(con->state));
6820                         }
6821 -                       
6822 +
6823                         if (-1 == connection_handle_write_prepare(srv, con)) {
6824                                 connection_set_state(srv, con, CON_STATE_ERROR);
6825 -                               
6826 +
6827                                 break;
6828                         }
6829 -                       
6830 +
6831                         connection_set_state(srv, con, CON_STATE_WRITE);
6832                         break;
6833                 case CON_STATE_RESPONSE_END: /* transient */
6834                         /* log the request */
6835 -                       
6836 +
6837                         if (srv->srvconf.log_state_handling) {
6838 -                               log_error_write(srv, __FILE__, __LINE__, "sds", 
6839 +                               log_error_write(srv, __FILE__, __LINE__, "sds",
6840                                                 "state for fd", con->fd, connection_get_state(con->state));
6841                         }
6842 -                       
6843 +
6844                         plugins_call_handle_request_done(srv, con);
6845 -                       
6846 +
6847                         srv->con_written++;
6848 -                       
6849 +
6850                         if (con->keep_alive) {
6851                                 connection_set_state(srv, con, CON_STATE_REQUEST_START);
6852 -                               
6853 -#if 0                                  
6854 +
6855 +#if 0
6856                                 con->request_start = srv->cur_ts;
6857                                 con->read_idle_ts = srv->cur_ts;
6858  #endif
6859 @@ -1482,7 +1394,7 @@
6860                                         log_error_write(srv, __FILE__, __LINE__, "sd", "unhandling return value", r);
6861                                         break;
6862                                 }
6863 -                               
6864 +
6865  #ifdef USE_OPENSSL
6866                                 if (srv_sock->is_ssl) {
6867                                         switch (SSL_shutdown(con->ssl)) {
6868 @@ -1490,44 +1402,44 @@
6869                                                 /* done */
6870                                                 break;
6871                                         case 0:
6872 -                                               /* wait for fd-event 
6873 -                                                * 
6874 +                                               /* wait for fd-event
6875 +                                                *
6876                                                  * FIXME: wait for fdevent and call SSL_shutdown again
6877 -                                                * 
6878 +                                                *
6879                                                  */
6880 -                                               
6881 +
6882                                                 break;
6883                                         default:
6884 -                                               log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
6885 +                                               log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
6886                                                                 ERR_error_string(ERR_get_error(), NULL));
6887                                         }
6888                                 }
6889  #endif
6890                                 connection_close(srv, con);
6891 -                               
6892 +
6893                                 srv->con_closed++;
6894                         }
6895 -                       
6896 +
6897                         connection_reset(srv, con);
6898 -                       
6899 +
6900                         break;
6901                 case CON_STATE_CONNECT:
6902                         if (srv->srvconf.log_state_handling) {
6903 -                               log_error_write(srv, __FILE__, __LINE__, "sds", 
6904 +                               log_error_write(srv, __FILE__, __LINE__, "sds",
6905                                                 "state for fd", con->fd, connection_get_state(con->state));
6906                         }
6907 -                       
6908 +
6909                         chunkqueue_reset(con->read_queue);
6910 -                       
6911 +
6912                         con->request_count = 0;
6913 -                       
6914 +
6915                         break;
6916                 case CON_STATE_CLOSE:
6917                         if (srv->srvconf.log_state_handling) {
6918 -                               log_error_write(srv, __FILE__, __LINE__, "sds", 
6919 +                               log_error_write(srv, __FILE__, __LINE__, "sds",
6920                                                 "state for fd", con->fd, connection_get_state(con->state));
6921                         }
6922 -                       
6923 +
6924                         if (con->keep_alive) {
6925                                 if (ioctl(con->fd, FIONREAD, &b)) {
6926                                         log_error_write(srv, __FILE__, __LINE__, "ss",
6927 @@ -1537,43 +1449,43 @@
6928                                         char buf[1024];
6929                                         log_error_write(srv, __FILE__, __LINE__, "sdd",
6930                                                         "CLOSE-read()", con->fd, b);
6931 -                                       
6932 +
6933                                         /* */
6934                                         read(con->fd, buf, sizeof(buf));
6935                                 } else {
6936                                         /* nothing to read */
6937 -                                       
6938 +
6939                                         con->close_timeout_ts = 0;
6940                                 }
6941                         } else {
6942                                 con->close_timeout_ts = 0;
6943                         }
6944 -                       
6945 +
6946                         if (srv->cur_ts - con->close_timeout_ts > 1) {
6947                                 connection_close(srv, con);
6948 -                               
6949 +
6950                                 if (srv->srvconf.log_state_handling) {
6951 -                                       log_error_write(srv, __FILE__, __LINE__, "sd", 
6952 +                                       log_error_write(srv, __FILE__, __LINE__, "sd",
6953                                                         "connection closed for fd", con->fd);
6954                                 }
6955                         }
6956 -                       
6957 +
6958                         break;
6959                 case CON_STATE_READ_POST:
6960                 case CON_STATE_READ:
6961                         if (srv->srvconf.log_state_handling) {
6962 -                               log_error_write(srv, __FILE__, __LINE__, "sds", 
6963 +                               log_error_write(srv, __FILE__, __LINE__, "sds",
6964                                                 "state for fd", con->fd, connection_get_state(con->state));
6965                         }
6966 -                       
6967 +
6968                         connection_handle_read_state(srv, con);
6969                         break;
6970                 case CON_STATE_WRITE:
6971                         if (srv->srvconf.log_state_handling) {
6972 -                               log_error_write(srv, __FILE__, __LINE__, "sds", 
6973 +                               log_error_write(srv, __FILE__, __LINE__, "sds",
6974                                                 "state for fd", con->fd, connection_get_state(con->state));
6975                         }
6976 -                       
6977 +
6978                         /* only try to write if we have something in the queue */
6979                         if (!chunkqueue_is_empty(con->write_queue)) {
6980  #if 0
6981 @@ -1593,10 +1505,10 @@
6982                                         con->write_request_ts = srv->cur_ts;
6983                                 }
6984                         }
6985 -                       
6986 +
6987                         break;
6988                 case CON_STATE_ERROR: /* transient */
6989 -                       
6990 +
6991                         /* even if the connection was drop we still have to write it to the access log */
6992                         if (con->http_status) {
6993                                 plugins_call_handle_request_done(srv, con);
6994 @@ -1612,19 +1524,19 @@
6995                                         SSL_shutdown(con->ssl);
6996                                         break;
6997                                 default:
6998 -                                       log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:", 
6999 -                                                       SSL_get_error(con->ssl, ret), 
7000 +                                       log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:",
7001 +                                                       SSL_get_error(con->ssl, ret),
7002                                                         ERR_error_string(ERR_get_error(), NULL));
7003                                         return -1;
7004                                 }
7005                         }
7006  #endif
7007 -                       
7008 +
7009                         switch(con->mode) {
7010                         case DIRECT:
7011  #if 0
7012 -                               log_error_write(srv, __FILE__, __LINE__, "sd", 
7013 -                                               "emergency exit: direct", 
7014 +                               log_error_write(srv, __FILE__, __LINE__, "sd",
7015 +                                               "emergency exit: direct",
7016                                                 con->fd);
7017  #endif
7018                                 break;
7019 @@ -1639,35 +1551,35 @@
7020                                 }
7021                                 break;
7022                         }
7023 -                       
7024 +
7025                         connection_reset(srv, con);
7026 -                       
7027 +
7028                         /* close the connection */
7029                         if ((con->keep_alive == 1) &&
7030                             (0 == shutdown(con->fd, SHUT_WR))) {
7031                                 con->close_timeout_ts = srv->cur_ts;
7032                                 connection_set_state(srv, con, CON_STATE_CLOSE);
7033 -                               
7034 +
7035                                 if (srv->srvconf.log_state_handling) {
7036 -                                       log_error_write(srv, __FILE__, __LINE__, "sd", 
7037 +                                       log_error_write(srv, __FILE__, __LINE__, "sd",
7038                                                         "shutdown for fd", con->fd);
7039                                 }
7040                         } else {
7041                                 connection_close(srv, con);
7042                         }
7043 -                       
7044 +
7045                         con->keep_alive = 0;
7046 -                       
7047 +
7048                         srv->con_closed++;
7049 -                       
7050 +
7051                         break;
7052                 default:
7053 -                       log_error_write(srv, __FILE__, __LINE__, "sdd", 
7054 +                       log_error_write(srv, __FILE__, __LINE__, "sdd",
7055                                         "unknown state:", con->fd, con->state);
7056 -                       
7057 +
7058                         break;
7059                 }
7060 -               
7061 +
7062                 if (done == -1) {
7063                         done = 0;
7064                 } else if (ostate == con->state) {
7065 @@ -1676,12 +1588,12 @@
7066         }
7067  
7068         if (srv->srvconf.log_state_handling) {
7069 -               log_error_write(srv, __FILE__, __LINE__, "sds", 
7070 -                               "state at exit:", 
7071 +               log_error_write(srv, __FILE__, __LINE__, "sds",
7072 +                               "state at exit:",
7073                                 con->fd,
7074                                 connection_get_state(con->state));
7075         }
7076 -       
7077 +
7078         switch(con->state) {
7079         case CON_STATE_READ_POST:
7080         case CON_STATE_READ:
7081 @@ -1689,11 +1601,11 @@
7082                 fdevent_event_add(srv->ev, &(con->fde_ndx), con->fd, FDEVENT_IN);
7083                 break;
7084         case CON_STATE_WRITE:
7085 -               /* request write-fdevent only if we really need it 
7086 +               /* request write-fdevent only if we really need it
7087                  * - if we have data to write
7088 -                * - if the socket is not writable yet 
7089 +                * - if the socket is not writable yet
7090                  */
7091 -               if (!chunkqueue_is_empty(con->write_queue) && 
7092 +               if (!chunkqueue_is_empty(con->write_queue) &&
7093                     (con->is_writable == 0) &&
7094                     (con->traffic_limit_reached == 0)) {
7095                         fdevent_event_add(srv->ev, &(con->fde_ndx), con->fd, FDEVENT_OUT);
7096
7097 Property changes on: src/connections.c
7098 ___________________________________________________________________
7099 Name: svn:eol-style
7100    + native
7101
7102 Index: src/array.h
7103 ===================================================================
7104 --- src/array.h (.../tags/lighttpd-1.4.11)      (revision 1159)
7105 +++ src/array.h (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
7106 @@ -16,7 +16,7 @@
7107  #define DATA_UNSET \
7108         data_type_t type; \
7109         buffer *key; \
7110 -       int is_index_key; /* 1 if key is a array index (autogenerated keys) */ \
7111 +       int is_index_key; /* 1 if key is an array index (auto-generated keys) */ \
7112         struct data_unset *(*copy)(const struct data_unset *src); \
7113         void (* free)(struct data_unset *p); \
7114         void (* reset)(struct data_unset *p); \
7115 @@ -29,21 +29,21 @@
7116  
7117  typedef struct {
7118         data_unset  **data;
7119 -       
7120 +
7121         size_t *sorted;
7122 -       
7123 +
7124         size_t used;
7125         size_t size;
7126 -       
7127 +
7128         size_t unique_ndx;
7129 -       
7130 +
7131         size_t next_power_of_2;
7132         int is_weakref; /* data is weakref, don't bother the data */
7133  } array;
7134  
7135  typedef struct {
7136         DATA_UNSET;
7137 -       
7138 +
7139         int count;
7140  } data_count;
7141  
7142 @@ -51,7 +51,7 @@
7143  
7144  typedef struct {
7145         DATA_UNSET;
7146 -       
7147 +
7148         buffer *value;
7149  } data_string;
7150  
7151 @@ -60,7 +60,7 @@
7152  
7153  typedef struct {
7154         DATA_UNSET;
7155 -       
7156 +
7157         array *value;
7158  } data_array;
7159  
7160 @@ -74,7 +74,7 @@
7161         COMP_SERVER_SOCKET, COMP_HTTP_URL, COMP_HTTP_HOST, COMP_HTTP_REFERER, COMP_HTTP_USERAGENT, COMP_HTTP_COOKIE, COMP_HTTP_REMOTEIP
7162  } comp_key_t;
7163  
7164 -/* $HTTP["host"] ==    "incremental.home.kneschke.de" { ... } 
7165 +/* $HTTP["host"] ==    "incremental.home.kneschke.de" { ... }
7166   * for print:   comp_key      op    string
7167   * for compare: comp          cond  string/regex
7168   */
7169 @@ -82,15 +82,15 @@
7170  typedef struct _data_config data_config;
7171  struct _data_config {
7172         DATA_UNSET;
7173 -       
7174 +
7175         array *value;
7176 -       
7177 +
7178         buffer *comp_key;
7179         comp_key_t comp;
7180 -       
7181 +
7182         config_cond_t cond;
7183         buffer *op;
7184 -       
7185 +
7186         int context_ndx; /* more or less like an id */
7187         array *childs;
7188         /* nested */
7189 @@ -98,7 +98,7 @@
7190         /* for chaining only */
7191         data_config *prev;
7192         data_config *next;
7193 -       
7194 +
7195         buffer *string;
7196  #ifdef HAVE_PCRE_H
7197         pcre   *regex;
7198 @@ -110,7 +110,7 @@
7199  
7200  typedef struct {
7201         DATA_UNSET;
7202 -       
7203 +
7204         int value;
7205  } data_integer;
7206  
7207 @@ -120,13 +120,13 @@
7208         DATA_UNSET;
7209  
7210         buffer *host;
7211 -       
7212 +
7213         unsigned short port;
7214  
7215         time_t disable_ts;
7216         int is_disabled;
7217         size_t balance;
7218 -               
7219 +
7220         int usage; /* fair-balancing needs the no. of connections active on this host */
7221         int last_used_ndx; /* round robin */
7222  } data_fastcgi;
7223
7224 Property changes on: src/array.h
7225 ___________________________________________________________________
7226 Name: svn:eol-style
7227    + native
7228
7229 Index: src/mod_staticfile.c
7230 ===================================================================
7231 --- src/mod_staticfile.c        (.../tags/lighttpd-1.4.11)      (revision 1159)
7232 +++ src/mod_staticfile.c        (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
7233 @@ -14,9 +14,11 @@
7234  #include "http_chunk.h"
7235  #include "response.h"
7236  
7237 +#include "sys-files.h"
7238 +#include "sys-strings.h"
7239  /**
7240   * this is a staticfile for a lighttpd plugin
7241 - * 
7242 + *
7243   */
7244  
7245  
7246 @@ -29,48 +31,48 @@
7247  
7248  typedef struct {
7249         PLUGIN_DATA;
7250 -       
7251 +
7252         buffer *range_buf;
7253 -       
7254 +
7255         plugin_config **config_storage;
7256 -       
7257 -       plugin_config conf; 
7258 +
7259 +       plugin_config conf;
7260  } plugin_data;
7261  
7262  /* init the plugin data */
7263  INIT_FUNC(mod_staticfile_init) {
7264         plugin_data *p;
7265 -       
7266 +
7267         p = calloc(1, sizeof(*p));
7268 -       
7269 +
7270         p->range_buf = buffer_init();
7271 -       
7272 +
7273         return p;
7274  }
7275  
7276 -/* detroy the plugin data */
7277 +/* destroy the plugin data */
7278  FREE_FUNC(mod_staticfile_free) {
7279         plugin_data *p = p_d;
7280 -       
7281 +
7282         UNUSED(srv);
7283  
7284         if (!p) return HANDLER_GO_ON;
7285 -       
7286 +
7287         if (p->config_storage) {
7288                 size_t i;
7289                 for (i = 0; i < srv->config_context->used; i++) {
7290                         plugin_config *s = p->config_storage[i];
7291 -                       
7292 +
7293                         array_free(s->exclude_ext);
7294 -                       
7295 +
7296                         free(s);
7297                 }
7298                 free(p->config_storage);
7299         }
7300         buffer_free(p->range_buf);
7301 -       
7302 +
7303         free(p);
7304 -       
7305 +
7306         return HANDLER_GO_ON;
7307  }
7308  
7309 @@ -79,63 +81,60 @@
7310  SETDEFAULTS_FUNC(mod_staticfile_set_defaults) {
7311         plugin_data *p = p_d;
7312         size_t i = 0;
7313 -       
7314 -       config_values_t cv[] = { 
7315 +
7316 +       config_values_t cv[] = {
7317                 { "static-file.exclude-extensions", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
7318                 { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
7319         };
7320 -       
7321 +
7322         if (!p) return HANDLER_ERROR;
7323 -       
7324 +
7325         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
7326 -       
7327 +
7328         for (i = 0; i < srv->config_context->used; i++) {
7329                 plugin_config *s;
7330 -               
7331 +
7332                 s = calloc(1, sizeof(plugin_config));
7333                 s->exclude_ext    = array_init();
7334 -               
7335 +
7336                 cv[0].destination = s->exclude_ext;
7337 -               
7338 +
7339                 p->config_storage[i] = s;
7340 -       
7341 +
7342                 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
7343                         return HANDLER_ERROR;
7344                 }
7345         }
7346 -       
7347 +
7348         return HANDLER_GO_ON;
7349  }
7350  
7351 -#define PATCH(x) \
7352 -       p->conf.x = s->x;
7353  static int mod_staticfile_patch_connection(server *srv, connection *con, plugin_data *p) {
7354         size_t i, j;
7355         plugin_config *s = p->config_storage[0];
7356 -       
7357 -       PATCH(exclude_ext);
7358 -       
7359 +
7360 +       PATCH_OPTION(exclude_ext);
7361 +
7362         /* skip the first, the global context */
7363         for (i = 1; i < srv->config_context->used; i++) {
7364                 data_config *dc = (data_config *)srv->config_context->data[i];
7365                 s = p->config_storage[i];
7366 -               
7367 +
7368                 /* condition didn't match */
7369                 if (!config_check_cond(srv, con, dc)) continue;
7370 -               
7371 +
7372                 /* merge config */
7373                 for (j = 0; j < dc->value->used; j++) {
7374                         data_unset *du = dc->value->data[j];
7375 -                       
7376 +
7377                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("static-file.exclude-extensions"))) {
7378 -                               PATCH(exclude_ext);
7379 +                               PATCH_OPTION(exclude_ext);
7380                         }
7381                 }
7382         }
7383 -       
7384 +
7385         return 0;
7386  }
7387 -#undef PATCH
7388  
7389  static int http_response_parse_range(server *srv, connection *con, plugin_data *p) {
7390         int multipart = 0;
7391 @@ -146,69 +145,69 @@
7392         data_string *ds;
7393         stat_cache_entry *sce = NULL;
7394         buffer *content_type = NULL;
7395 -       
7396 +
7397         if (HANDLER_ERROR == stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
7398                 SEGFAULT();
7399         }
7400 -       
7401 +
7402         start = 0;
7403         end = sce->st.st_size - 1;
7404 -       
7405 +
7406         con->response.content_length = 0;
7407 -       
7408 +
7409         if (NULL != (ds = (data_string *)array_get_element(con->response.headers, "Content-Type"))) {
7410                 content_type = ds->value;
7411         }
7412 -       
7413 +
7414         for (s = con->request.http_range, error = 0;
7415              !error && *s && NULL != (minus = strchr(s, '-')); ) {
7416                 char *err;
7417                 off_t la, le;
7418 -               
7419 +
7420                 if (s == minus) {
7421                         /* -<stop> */
7422 -                       
7423 +
7424                         le = strtoll(s, &err, 10);
7425 -                       
7426 +
7427                         if (le == 0) {
7428                                 /* RFC 2616 - 14.35.1 */
7429 -                               
7430 +
7431                                 con->http_status = 416;
7432                                 error = 1;
7433                         } else if (*err == '\0') {
7434                                 /* end */
7435                                 s = err;
7436 -                               
7437 +
7438                                 end = sce->st.st_size - 1;
7439                                 start = sce->st.st_size + le;
7440                         } else if (*err == ',') {
7441                                 multipart = 1;
7442                                 s = err + 1;
7443 -                               
7444 +
7445                                 end = sce->st.st_size - 1;
7446                                 start = sce->st.st_size + le;
7447                         } else {
7448                                 error = 1;
7449                         }
7450 -                       
7451 +
7452                 } else if (*(minus+1) == '\0' || *(minus+1) == ',') {
7453                         /* <start>- */
7454 -                       
7455 +
7456                         la = strtoll(s, &err, 10);
7457 -                       
7458 +
7459                         if (err == minus) {
7460                                 /* ok */
7461 -                               
7462 +
7463                                 if (*(err + 1) == '\0') {
7464                                         s = err + 1;
7465 -                                       
7466 +
7467                                         end = sce->st.st_size - 1;
7468                                         start = la;
7469 -                                       
7470 +
7471                                 } else if (*(err + 1) == ',') {
7472                                         multipart = 1;
7473                                         s = err + 2;
7474 -                                       
7475 +
7476                                         end = sce->st.st_size - 1;
7477                                         start = la;
7478                                 } else {
7479 @@ -220,64 +219,64 @@
7480                         }
7481                 } else {
7482                         /* <start>-<stop> */
7483 -                       
7484 +
7485                         la = strtoll(s, &err, 10);
7486 -                       
7487 +
7488                         if (err == minus) {
7489                                 le = strtoll(minus+1, &err, 10);
7490 -                               
7491 +
7492                                 /* RFC 2616 - 14.35.1 */
7493                                 if (la > le) {
7494                                         error = 1;
7495                                 }
7496 -                                       
7497 +
7498                                 if (*err == '\0') {
7499                                         /* ok, end*/
7500                                         s = err;
7501 -                                       
7502 +
7503                                         end = le;
7504                                         start = la;
7505                                 } else if (*err == ',') {
7506                                         multipart = 1;
7507                                         s = err + 1;
7508 -                                       
7509 +
7510                                         end = le;
7511                                         start = la;
7512                                 } else {
7513                                         /* error */
7514 -                                       
7515 +
7516                                         error = 1;
7517                                 }
7518                         } else {
7519                                 /* error */
7520 -                               
7521 +
7522                                 error = 1;
7523                         }
7524                 }
7525 -               
7526 +
7527                 if (!error) {
7528                         if (start < 0) start = 0;
7529 -                       
7530 +
7531                         /* RFC 2616 - 14.35.1 */
7532                         if (end > sce->st.st_size - 1) end = sce->st.st_size - 1;
7533 -                       
7534 +
7535                         if (start > sce->st.st_size - 1) {
7536                                 error = 1;
7537 -                               
7538 +
7539                                 con->http_status = 416;
7540                         }
7541                 }
7542 -               
7543 +
7544                 if (!error) {
7545                         if (multipart) {
7546                                 /* write boundary-header */
7547                                 buffer *b;
7548 -                               
7549 +
7550                                 b = chunkqueue_get_append_buffer(con->write_queue);
7551 -                               
7552 +
7553                                 buffer_copy_string(b, "\r\n--");
7554                                 buffer_append_string(b, boundary);
7555 -                               
7556 +
7557                                 /* write Content-Range */
7558                                 buffer_append_string(b, "\r\nContent-Range: bytes ");
7559                                 buffer_append_off_t(b, start);
7560 @@ -285,54 +284,54 @@
7561                                 buffer_append_off_t(b, end);
7562                                 buffer_append_string(b, "/");
7563                                 buffer_append_off_t(b, sce->st.st_size);
7564 -                               
7565 +
7566                                 buffer_append_string(b, "\r\nContent-Type: ");
7567                                 buffer_append_string_buffer(b, content_type);
7568 -                               
7569 +
7570                                 /* write END-OF-HEADER */
7571                                 buffer_append_string(b, "\r\n\r\n");
7572 -                               
7573 +
7574                                 con->response.content_length += b->used - 1;
7575 -                               
7576 +
7577                         }
7578 -                       
7579 +
7580                         chunkqueue_append_file(con->write_queue, con->physical.path, start, end - start + 1);
7581                         con->response.content_length += end - start + 1;
7582                 }
7583         }
7584 -       
7585 +
7586         /* something went wrong */
7587         if (error) return -1;
7588 -       
7589 +
7590         if (multipart) {
7591                 /* add boundary end */
7592                 buffer *b;
7593 -               
7594 +
7595                 b = chunkqueue_get_append_buffer(con->write_queue);
7596 -               
7597 +
7598                 buffer_copy_string_len(b, "\r\n--", 4);
7599                 buffer_append_string(b, boundary);
7600                 buffer_append_string_len(b, "--\r\n", 4);
7601 -               
7602 +
7603                 con->response.content_length += b->used - 1;
7604 -               
7605 +
7606                 /* set header-fields */
7607 -               
7608 +
7609                 buffer_copy_string(p->range_buf, "multipart/byteranges; boundary=");
7610                 buffer_append_string(p->range_buf, boundary);
7611 -               
7612 +
7613                 /* overwrite content-type */
7614                 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(p->range_buf));
7615         } else {
7616                 /* add Content-Range-header */
7617 -               
7618 +
7619                 buffer_copy_string(p->range_buf, "bytes ");
7620                 buffer_append_off_t(p->range_buf, start);
7621                 buffer_append_string(p->range_buf, "-");
7622                 buffer_append_off_t(p->range_buf, end);
7623                 buffer_append_string(p->range_buf, "/");
7624                 buffer_append_off_t(p->range_buf, sce->st.st_size);
7625 -               
7626 +
7627                 response_header_insert(srv, con, CONST_STR_LEN("Content-Range"), CONST_BUF_LEN(p->range_buf));
7628         }
7629  
7630 @@ -347,12 +346,12 @@
7631         stat_cache_entry *sce = NULL;
7632         buffer *mtime;
7633         data_string *ds;
7634 -       
7635 +
7636         /* someone else has done a decision for us */
7637         if (con->http_status != 0) return HANDLER_GO_ON;
7638         if (con->uri.path->used == 0) return HANDLER_GO_ON;
7639         if (con->physical.path->used == 0) return HANDLER_GO_ON;
7640 -       
7641 +
7642         /* someone else has handled this request */
7643         if (con->mode != DIRECT) return HANDLER_GO_ON;
7644  
7645 @@ -365,52 +364,52 @@
7646         default:
7647                 return HANDLER_GO_ON;
7648         }
7649 -       
7650 +
7651         mod_staticfile_patch_connection(srv, con, p);
7652 -       
7653 +
7654         s_len = con->uri.path->used - 1;
7655 -       
7656 +
7657         /* ignore certain extensions */
7658         for (k = 0; k < p->conf.exclude_ext->used; k++) {
7659 -               ds = (data_string *)p->conf.exclude_ext->data[k]; 
7660 -               
7661 +               ds = (data_string *)p->conf.exclude_ext->data[k];
7662 +
7663                 if (ds->value->used == 0) continue;
7664  
7665                 if (buffer_is_equal_right_len(con->physical.path, ds->value, ds->value->used - 1)) {
7666                         return HANDLER_GO_ON;
7667                 }
7668         }
7669 -       
7670  
7671 +
7672         if (con->conf.log_request_handling) {
7673                 log_error_write(srv, __FILE__, __LINE__,  "s",  "-- handling file as static file");
7674         }
7675 -       
7676 +
7677         if (HANDLER_ERROR == stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
7678                 con->http_status = 403;
7679 -               
7680 +
7681                 log_error_write(srv, __FILE__, __LINE__, "sbsb",
7682                                 "not a regular file:", con->uri.path,
7683                                 "->", con->physical.path);
7684 -               
7685 +
7686                 return HANDLER_FINISHED;
7687         }
7688 -       
7689 -       /* we only handline regular files */
7690 +
7691 +       /* we only handle regular files */
7692         if (!S_ISREG(sce->st.st_mode)) {
7693                 con->http_status = 404;
7694 -               
7695 +
7696                 if (con->conf.log_file_not_found) {
7697                         log_error_write(srv, __FILE__, __LINE__, "sbsb",
7698                                         "not a regular file:", con->uri.path,
7699                                         "->", sce->name);
7700                 }
7701 -               
7702 +
7703                 return HANDLER_FINISHED;
7704         }
7705  
7706 -       /* mod_compress might set several data directly, don't overwrite them */
7707 -       
7708 +       /* mod_compress might set several parameters directly; don't overwrite them */
7709 +
7710         /* set response content-type, if not set already */
7711  
7712         if (NULL == array_get_element(con->response.headers, "Content-Type")) {
7713 @@ -420,15 +419,15 @@
7714                         response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type));
7715                 }
7716         }
7717 -       
7718 +
7719         if (NULL == array_get_element(con->response.headers, "ETag")) {
7720                 /* generate e-tag */
7721                 etag_mutate(con->physical.etag, sce->etag);
7722 -       
7723 +
7724                 response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag));
7725         }
7726         response_header_overwrite(srv, con, CONST_STR_LEN("Accept-Ranges"), CONST_STR_LEN("bytes"));
7727 -       
7728 +
7729         /* prepare header */
7730         if (NULL == (ds = (data_string *)array_get_element(con->response.headers, "Last-Modified"))) {
7731                 mtime = strftime_cache_get(srv, sce->st.st_mtime);
7732 @@ -444,34 +443,34 @@
7733                 /* check if we have a conditional GET */
7734  
7735                 if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "If-Range"))) {
7736 -                       /* if the value is the same as our ETag, we do a Range-request, 
7737 +                       /* if the value is the same as our ETag, we do a Range-request,
7738                          * otherwise a full 200 */
7739  
7740                         if (!buffer_is_equal(ds->value, con->physical.etag)) {
7741                                 do_range_request = 0;
7742                         }
7743                 }
7744 -       
7745 +
7746                 if (do_range_request) {
7747                         /* content prepared, I'm done */
7748                         con->file_finished = 1;
7749 -               
7750 +
7751                         if (0 == http_response_parse_range(srv, con, p)) {
7752                                 con->http_status = 206;
7753                         }
7754                         return HANDLER_FINISHED;
7755                 }
7756         }
7757 -       
7758 +
7759         /* if we are still here, prepare body */
7760 -       
7761 -       /* we add it here for all requests 
7762 -        * the HEAD request will drop it afterwards again 
7763 +
7764 +       /* we add it here for all requests
7765 +        * the HEAD request will drop it afterwards again
7766          */
7767         http_chunk_append_file(srv, con, con->physical.path, 0, sce->st.st_size);
7768 -       
7769 +
7770         con->file_finished = 1;
7771 -       
7772 +
7773         return HANDLER_FINISHED;
7774  }
7775  
7776 @@ -480,13 +479,13 @@
7777  int mod_staticfile_plugin_init(plugin *p) {
7778         p->version     = LIGHTTPD_VERSION_ID;
7779         p->name        = buffer_init_string("staticfile");
7780 -       
7781 +
7782         p->init        = mod_staticfile_init;
7783         p->handle_subrequest_start = mod_staticfile_subrequest;
7784         p->set_defaults  = mod_staticfile_set_defaults;
7785         p->cleanup     = mod_staticfile_free;
7786 -       
7787 +
7788         p->data        = NULL;
7789 -       
7790 +
7791         return 0;
7792  }
7793
7794 Property changes on: src/mod_staticfile.c
7795 ___________________________________________________________________
7796 Name: svn:eol-style
7797    + native
7798
7799 Index: src/data_integer.c
7800 ===================================================================
7801 --- src/data_integer.c  (.../tags/lighttpd-1.4.11)      (revision 1159)
7802 +++ src/data_integer.c  (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
7803 @@ -16,15 +16,15 @@
7804  
7805  static void data_integer_free(data_unset *d) {
7806         data_integer *ds = (data_integer *)d;
7807 -       
7808 +
7809         buffer_free(ds->key);
7810 -       
7811 +
7812         free(d);
7813  }
7814  
7815  static void data_integer_reset(data_unset *d) {
7816         data_integer *ds = (data_integer *)d;
7817 -       
7818 +
7819         /* reused integer elements */
7820         buffer_reset(ds->key);
7821         ds->value = 0;
7822 @@ -32,9 +32,9 @@
7823  
7824  static int data_integer_insert_dup(data_unset *dst, data_unset *src) {
7825         UNUSED(dst);
7826 -       
7827 +
7828         src->free(src);
7829 -       
7830 +
7831         return 0;
7832  }
7833  
7834 @@ -48,18 +48,18 @@
7835  
7836  data_integer *data_integer_init(void) {
7837         data_integer *ds;
7838 -       
7839 +
7840         ds = calloc(1, sizeof(*ds));
7841 -       
7842 +
7843         ds->key = buffer_init();
7844         ds->value = 0;
7845 -       
7846 +
7847         ds->copy = data_integer_copy;
7848         ds->free = data_integer_free;
7849         ds->reset = data_integer_reset;
7850         ds->insert_dup = data_integer_insert_dup;
7851         ds->print = data_integer_print;
7852         ds->type = TYPE_INTEGER;
7853 -       
7854 +
7855         return ds;
7856  }
7857
7858 Property changes on: src/data_integer.c
7859 ___________________________________________________________________
7860 Name: svn:eol-style
7861    + native
7862
7863
7864 Property changes on: src/connections.h
7865 ___________________________________________________________________
7866 Name: svn:eol-style
7867    + native
7868
7869 Index: src/mod_alias.c
7870 ===================================================================
7871 --- src/mod_alias.c     (.../tags/lighttpd-1.4.11)      (revision 1159)
7872 +++ src/mod_alias.c     (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
7873 @@ -8,6 +8,7 @@
7874  #include "buffer.h"
7875  
7876  #include "plugin.h"
7877 +#include "sys-strings.h"
7878  
7879  /* plugin config for all request/connections */
7880  typedef struct {
7881 @@ -16,44 +17,44 @@
7882  
7883  typedef struct {
7884         PLUGIN_DATA;
7885 -       
7886 +
7887         plugin_config **config_storage;
7888 -       
7889 -       plugin_config conf; 
7890 +
7891 +       plugin_config conf;
7892  } plugin_data;
7893  
7894  /* init the plugin data */
7895  INIT_FUNC(mod_alias_init) {
7896         plugin_data *p;
7897 -       
7898 +
7899         p = calloc(1, sizeof(*p));
7900 -       
7901 -       
7902 -       
7903 +
7904 +
7905 +
7906         return p;
7907  }
7908  
7909  /* detroy the plugin data */
7910  FREE_FUNC(mod_alias_free) {
7911         plugin_data *p = p_d;
7912 -       
7913 +
7914         if (!p) return HANDLER_GO_ON;
7915 -       
7916 +
7917         if (p->config_storage) {
7918                 size_t i;
7919 -               
7920 +
7921                 for (i = 0; i < srv->config_context->used; i++) {
7922                         plugin_config *s = p->config_storage[i];
7923 -                       
7924 +
7925                         array_free(s->alias);
7926 -                       
7927 +
7928                         free(s);
7929                 }
7930                 free(p->config_storage);
7931         }
7932 -       
7933 +
7934         free(p);
7935 -       
7936 +
7937         return HANDLER_GO_ON;
7938  }
7939  
7940 @@ -62,25 +63,25 @@
7941  SETDEFAULTS_FUNC(mod_alias_set_defaults) {
7942         plugin_data *p = p_d;
7943         size_t i = 0;
7944 -       
7945 -       config_values_t cv[] = { 
7946 +
7947 +       config_values_t cv[] = {
7948                 { "alias.url",                  NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
7949                 { NULL,                         NULL, T_CONFIG_UNSET,  T_CONFIG_SCOPE_UNSET }
7950         };
7951 -       
7952 +
7953         if (!p) return HANDLER_ERROR;
7954 -       
7955 +
7956         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
7957 -       
7958 +
7959         for (i = 0; i < srv->config_context->used; i++) {
7960                 plugin_config *s;
7961 -               
7962 +
7963                 s = calloc(1, sizeof(plugin_config));
7964 -               s->alias = array_init();        
7965 +               s->alias = array_init();
7966                 cv[0].destination = s->alias;
7967 -               
7968 +
7969                 p->config_storage[i] = s;
7970 -               
7971 +
7972                 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
7973                         return HANDLER_ERROR;
7974                 }
7975 @@ -110,76 +111,73 @@
7976                         }
7977                 }
7978         }
7979 -       
7980 +
7981         return HANDLER_GO_ON;
7982  }
7983  
7984 -#define PATCH(x) \
7985 -       p->conf.x = s->x;
7986  static int mod_alias_patch_connection(server *srv, connection *con, plugin_data *p) {
7987         size_t i, j;
7988         plugin_config *s = p->config_storage[0];
7989 -       
7990 -       PATCH(alias);
7991 -       
7992 +
7993 +       PATCH_OPTION(alias);
7994 +
7995         /* skip the first, the global context */
7996         for (i = 1; i < srv->config_context->used; i++) {
7997                 data_config *dc = (data_config *)srv->config_context->data[i];
7998                 s = p->config_storage[i];
7999 -               
8000 +
8001                 /* condition didn't match */
8002                 if (!config_check_cond(srv, con, dc)) continue;
8003 -               
8004 +
8005                 /* merge config */
8006                 for (j = 0; j < dc->value->used; j++) {
8007                         data_unset *du = dc->value->data[j];
8008 -                       
8009 +
8010                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("alias.url"))) {
8011 -                               PATCH(alias);
8012 +                               PATCH_OPTION(alias);
8013                         }
8014                 }
8015         }
8016 -       
8017 +
8018         return 0;
8019  }
8020 -#undef PATCH
8021  
8022  PHYSICALPATH_FUNC(mod_alias_physical_handler) {
8023         plugin_data *p = p_d;
8024         int uri_len, basedir_len;
8025         char *uri_ptr;
8026         size_t k;
8027 -       
8028 +
8029         if (con->physical.path->used == 0) return HANDLER_GO_ON;
8030 -       
8031 +
8032         mod_alias_patch_connection(srv, con, p);
8033 -       
8034 +
8035         /* not to include the tailing slash */
8036         basedir_len = (con->physical.basedir->used - 1) - 1;
8037         uri_len = con->physical.path->used - 1 - basedir_len;
8038         uri_ptr = con->physical.path->ptr + basedir_len;
8039 -       
8040 +
8041         for (k = 0; k < p->conf.alias->used; k++) {
8042                 data_string *ds = (data_string *)p->conf.alias->data[k];
8043                 int alias_len = ds->key->used - 1;
8044 -               
8045 +
8046                 if (alias_len > uri_len) continue;
8047                 if (ds->key->used == 0) continue;
8048 -               
8049 +
8050                 if (0 == (con->conf.force_lowercase_filenames ?
8051                                         strncasecmp(uri_ptr, ds->key->ptr, alias_len) :
8052                                         strncmp(uri_ptr, ds->key->ptr, alias_len))) {
8053                         /* matched */
8054 -                       
8055 +
8056                         buffer_copy_string_buffer(con->physical.basedir, ds->value);
8057                         buffer_copy_string_buffer(srv->tmp_buf, ds->value);
8058                         buffer_append_string(srv->tmp_buf, uri_ptr + alias_len);
8059                         buffer_copy_string_buffer(con->physical.path, srv->tmp_buf);
8060 -                       
8061 +
8062                         return HANDLER_GO_ON;
8063                 }
8064         }
8065 -       
8066 +
8067         /* not found */
8068         return HANDLER_GO_ON;
8069  }
8070 @@ -189,13 +187,13 @@
8071  int mod_alias_plugin_init(plugin *p) {
8072         p->version     = LIGHTTPD_VERSION_ID;
8073         p->name        = buffer_init_string("alias");
8074 -       
8075 +
8076         p->init           = mod_alias_init;
8077         p->handle_physical= mod_alias_physical_handler;
8078         p->set_defaults   = mod_alias_set_defaults;
8079         p->cleanup        = mod_alias_free;
8080 -       
8081 +
8082         p->data        = NULL;
8083 -       
8084 +
8085         return 0;
8086  }
8087
8088 Property changes on: src/mod_alias.c
8089 ___________________________________________________________________
8090 Name: svn:eol-style
8091    + native
8092
8093 Index: src/network.c
8094 ===================================================================
8095 --- src/network.c       (.../tags/lighttpd-1.4.11)      (revision 1159)
8096 +++ src/network.c       (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
8097 @@ -1,14 +1,14 @@
8098  #include <sys/types.h>
8099  #include <sys/stat.h>
8100 -#include <sys/time.h>
8101  
8102  #include <errno.h>
8103  #include <fcntl.h>
8104 -#include <unistd.h>
8105  #include <string.h>
8106  #include <stdlib.h>
8107  #include <assert.h>
8108  
8109 +#include <stdio.h>
8110 +
8111  #include "network.h"
8112  #include "fdevent.h"
8113  #include "log.h"
8114 @@ -19,11 +19,12 @@
8115  #include "network_backends.h"
8116  #include "sys-mmap.h"
8117  #include "sys-socket.h"
8118 +#include "sys-files.h"
8119  
8120  #ifdef USE_OPENSSL
8121 -# include <openssl/ssl.h> 
8122 -# include <openssl/err.h> 
8123 -# include <openssl/rand.h> 
8124 +# include <openssl/ssl.h>
8125 +# include <openssl/err.h>
8126 +# include <openssl/rand.h>
8127  #endif
8128  
8129  handler_t network_server_handle_fdevent(void *s, void *context, int revents) {
8130 @@ -31,11 +32,11 @@
8131         server_socket *srv_socket = (server_socket *)context;
8132         connection *con;
8133         int loops = 0;
8134 -       
8135 +
8136         UNUSED(context);
8137 -       
8138 +
8139         if (revents != FDEVENT_IN) {
8140 -               log_error_write(srv, __FILE__, __LINE__, "sdd", 
8141 +               log_error_write(srv, __FILE__, __LINE__, "sdd",
8142                                 "strange event for server socket",
8143                                 srv_socket->fd,
8144                                 revents);
8145 @@ -44,12 +45,12 @@
8146  
8147         /* accept()s at most 100 connections directly
8148          *
8149 -        * we jump out after 100 to give the waiting connections a chance */    
8150 +        * we jump out after 100 to give the waiting connections a chance */
8151         for (loops = 0; loops < 100 && NULL != (con = connection_accept(srv, srv_socket)); loops++) {
8152                 handler_t r;
8153 -               
8154 +
8155                 connection_state_machine(srv, con);
8156 -               
8157 +
8158                 switch(r = plugins_call_handle_joblist(srv, con)) {
8159                 case HANDLER_FINISHED:
8160                 case HANDLER_GO_ON:
8161 @@ -72,18 +73,18 @@
8162         buffer *b;
8163         int is_unix_domain_socket = 0;
8164         int fd;
8165 -       
8166 +
8167  #ifdef SO_ACCEPTFILTER
8168         struct accept_filter_arg afa;
8169  #endif
8170  
8171 -#ifdef __WIN32
8172 +#ifdef _WIN32
8173         WORD wVersionRequested;
8174         WSADATA wsaData;
8175         int err;
8176 -        
8177 +
8178         wVersionRequested = MAKEWORD( 2, 2 );
8179 -        
8180 +
8181         err = WSAStartup( wVersionRequested, &wsaData );
8182         if ( err != 0 ) {
8183                     /* Tell the user that we could not find a usable */
8184 @@ -91,37 +92,37 @@
8185                     return -1;
8186         }
8187  #endif
8188 -       
8189 +
8190         srv_socket = calloc(1, sizeof(*srv_socket));
8191         srv_socket->fd = -1;
8192 -       
8193 +
8194         srv_socket->srv_token = buffer_init();
8195         buffer_copy_string_buffer(srv_socket->srv_token, host_token);
8196 -       
8197 +
8198         b = buffer_init();
8199         buffer_copy_string_buffer(b, host_token);
8200 -       
8201 -       /* ipv4:port 
8202 +
8203 +       /* ipv4:port
8204          * [ipv6]:port
8205          */
8206         if (NULL == (sp = strrchr(b->ptr, ':'))) {
8207                 log_error_write(srv, __FILE__, __LINE__, "sb", "value of $SERVER[\"socket\"] has to be \"ip:port\".", b);
8208 -               
8209 +
8210                 return -1;
8211         }
8212 -       
8213 +
8214         host = b->ptr;
8215 -       
8216 +
8217         /* check for [ and ] */
8218         if (b->ptr[0] == '[' && *(sp-1) == ']') {
8219                 *(sp-1) = '\0';
8220                 host++;
8221 -               
8222 +
8223                 s->use_ipv6 = 1;
8224         }
8225 -       
8226 +
8227         *(sp++) = '\0';
8228 -       
8229 +
8230         port = strtol(sp, NULL, 10);
8231  
8232         if (host[0] == '/') {
8233 @@ -129,17 +130,17 @@
8234                 is_unix_domain_socket = 1;
8235         } else if (port == 0 || port > 65535) {
8236                 log_error_write(srv, __FILE__, __LINE__, "sd", "port out of range:", port);
8237 -       
8238 +
8239                 return -1;
8240         }
8241 -       
8242 +
8243         if (*host == '\0') host = NULL;
8244  
8245         if (is_unix_domain_socket) {
8246  #ifdef HAVE_SYS_UN_H
8247  
8248                 srv_socket->addr.plain.sa_family = AF_UNIX;
8249 -               
8250 +
8251                 if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, 0))) {
8252                         log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno));
8253                         return -1;
8254 @@ -154,7 +155,7 @@
8255  #ifdef HAVE_IPV6
8256         if (s->use_ipv6) {
8257                 srv_socket->addr.plain.sa_family = AF_INET6;
8258 -               
8259 +
8260                 if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, IPPROTO_TCP))) {
8261                         log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno));
8262                         return -1;
8263 @@ -162,7 +163,7 @@
8264                 srv_socket->use_ipv6 = 1;
8265         }
8266  #endif
8267 -                               
8268 +
8269         if (srv_socket->fd == -1) {
8270                 srv_socket->addr.plain.sa_family = AF_INET;
8271                 if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, IPPROTO_TCP))) {
8272 @@ -170,16 +171,16 @@
8273                         return -1;
8274                 }
8275         }
8276 -       
8277 +
8278         /* */
8279         srv->cur_fds = srv_socket->fd;
8280 -       
8281 +
8282         val = 1;
8283         if (setsockopt(srv_socket->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
8284                 log_error_write(srv, __FILE__, __LINE__, "ss", "socketsockopt failed:", strerror(errno));
8285                 return -1;
8286         }
8287 -       
8288 +
8289         switch(srv_socket->addr.plain.sa_family) {
8290  #ifdef HAVE_IPV6
8291         case AF_INET6:
8292 @@ -190,23 +191,23 @@
8293                 } else {
8294                         struct addrinfo hints, *res;
8295                         int r;
8296 -                       
8297 +
8298                         memset(&hints, 0, sizeof(hints));
8299 -                       
8300 +
8301                         hints.ai_family   = AF_INET6;
8302                         hints.ai_socktype = SOCK_STREAM;
8303                         hints.ai_protocol = IPPROTO_TCP;
8304 -                       
8305 +
8306                         if (0 != (r = getaddrinfo(host, NULL, &hints, &res))) {
8307 -                               log_error_write(srv, __FILE__, __LINE__, 
8308 -                                               "sssss", "getaddrinfo failed: ", 
8309 +                               log_error_write(srv, __FILE__, __LINE__,
8310 +                                               "sssss", "getaddrinfo failed: ",
8311                                                 gai_strerror(r), "'", host, "'");
8312 -                               
8313 +
8314                                 return -1;
8315                         }
8316 -                       
8317 +
8318                         memcpy(&(srv_socket->addr), res->ai_addr, res->ai_addrlen);
8319 -                       
8320 +
8321                         freeaddrinfo(res);
8322                 }
8323                 srv_socket->addr.ipv6.sin6_port = htons(port);
8324 @@ -221,33 +222,34 @@
8325                 } else {
8326                         struct hostent *he;
8327                         if (NULL == (he = gethostbyname(host))) {
8328 -                               log_error_write(srv, __FILE__, __LINE__, 
8329 -                                               "sds", "gethostbyname failed: ", 
8330 +                               log_error_write(srv, __FILE__, __LINE__,
8331 +                                               "sds", "gethostbyname failed: ",
8332                                                 h_errno, host);
8333                                 return -1;
8334                         }
8335 -                       
8336 +
8337                         if (he->h_addrtype != AF_INET) {
8338                                 log_error_write(srv, __FILE__, __LINE__, "sd", "addr-type != AF_INET: ", he->h_addrtype);
8339                                 return -1;
8340                         }
8341 -                       
8342 +
8343                         if (he->h_length != sizeof(struct in_addr)) {
8344                                 log_error_write(srv, __FILE__, __LINE__, "sd", "addr-length != sizeof(in_addr): ", he->h_length);
8345                                 return -1;
8346                         }
8347 -                       
8348 +
8349                         memcpy(&(srv_socket->addr.ipv4.sin_addr.s_addr), he->h_addr_list[0], he->h_length);
8350                 }
8351                 srv_socket->addr.ipv4.sin_port = htons(port);
8352 -               
8353 +
8354                 addr_len = sizeof(struct sockaddr_in);
8355 -               
8356 +
8357                 break;
8358 +#ifndef _WIN32
8359         case AF_UNIX:
8360                 srv_socket->addr.un.sun_family = AF_UNIX;
8361                 strcpy(srv_socket->addr.un.sun_path, host);
8362 -               
8363 +
8364  #ifdef SUN_LEN
8365                 addr_len = SUN_LEN(&srv_socket->addr.un);
8366  #else
8367 @@ -259,8 +261,8 @@
8368                 if (-1 != (fd = connect(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len))) {
8369                         close(fd);
8370  
8371 -                       log_error_write(srv, __FILE__, __LINE__, "ss", 
8372 -                               "server socket is still in use:", 
8373 +                       log_error_write(srv, __FILE__, __LINE__, "ss",
8374 +                               "server socket is still in use:",
8375                                 host);
8376  
8377  
8378 @@ -275,88 +277,89 @@
8379                 case ENOENT:
8380                         break;
8381                 default:
8382 -                       log_error_write(srv, __FILE__, __LINE__, "sds", 
8383 -                               "testing socket failed:", 
8384 +                       log_error_write(srv, __FILE__, __LINE__, "sds",
8385 +                               "testing socket failed:",
8386                                 host, strerror(errno));
8387  
8388                         return -1;
8389                 }
8390  
8391                 break;
8392 +#endif
8393         default:
8394                 addr_len = 0;
8395 -               
8396 +
8397                 return -1;
8398         }
8399 -       
8400 +
8401         if (0 != bind(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len)) {
8402                 switch(srv_socket->addr.plain.sa_family) {
8403                 case AF_UNIX:
8404 -                       log_error_write(srv, __FILE__, __LINE__, "sds", 
8405 -                                       "can't bind to socket:", 
8406 +                       log_error_write(srv, __FILE__, __LINE__, "sds",
8407 +                                       "can't bind to socket:",
8408                                         host, strerror(errno));
8409                         break;
8410                 default:
8411 -                       log_error_write(srv, __FILE__, __LINE__, "ssds", 
8412 -                                       "can't bind to port:", 
8413 +                       log_error_write(srv, __FILE__, __LINE__, "ssds",
8414 +                                       "can't bind to port:",
8415                                         host, port, strerror(errno));
8416                         break;
8417                 }
8418                 return -1;
8419         }
8420 -       
8421 +
8422         if (-1 == listen(srv_socket->fd, 128 * 8)) {
8423                 log_error_write(srv, __FILE__, __LINE__, "ss", "listen failed: ", strerror(errno));
8424                 return -1;
8425         }
8426 -       
8427 +
8428         if (s->is_ssl) {
8429  #ifdef USE_OPENSSL
8430                 if (srv->ssl_is_init == 0) {
8431                         SSL_load_error_strings();
8432                         SSL_library_init();
8433                         srv->ssl_is_init = 1;
8434 -                       
8435 +
8436                         if (0 == RAND_status()) {
8437 -                               log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
8438 +                               log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
8439                                                 "not enough entropy in the pool");
8440                                 return -1;
8441                         }
8442                 }
8443 -               
8444 +
8445                 if (NULL == (s->ssl_ctx = SSL_CTX_new(SSLv23_server_method()))) {
8446 -                       log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
8447 +                       log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
8448                                         ERR_error_string(ERR_get_error(), NULL));
8449                         return -1;
8450                 }
8451 -               
8452 +
8453                 if (buffer_is_empty(s->ssl_pemfile)) {
8454                         log_error_write(srv, __FILE__, __LINE__, "s", "ssl.pemfile has to be set");
8455                         return -1;
8456                 }
8457 -               
8458 +
8459                 if (!buffer_is_empty(s->ssl_ca_file)) {
8460                         if (1 != SSL_CTX_load_verify_locations(s->ssl_ctx, s->ssl_ca_file->ptr, NULL)) {
8461 -                               log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", 
8462 +                               log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
8463                                                 ERR_error_string(ERR_get_error(), NULL), s->ssl_ca_file);
8464                                 return -1;
8465                         }
8466                 }
8467 -               
8468 +
8469                 if (SSL_CTX_use_certificate_file(s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) {
8470 -                       log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", 
8471 +                       log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
8472                                         ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile);
8473                         return -1;
8474                 }
8475 -               
8476 +
8477                 if (SSL_CTX_use_PrivateKey_file (s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) {
8478 -                       log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", 
8479 +                       log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
8480                                         ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile);
8481                         return -1;
8482                 }
8483 -               
8484 +
8485                 if (SSL_CTX_check_private_key(s->ssl_ctx) != 1) {
8486 -                       log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:", 
8487 +                       log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:",
8488                                         "Private key does not match the certificate public key, reason:",
8489                                         ERR_error_string(ERR_get_error(), NULL),
8490                                         s->ssl_pemfile);
8491 @@ -364,15 +367,15 @@
8492                 }
8493                 srv_socket->ssl_ctx = s->ssl_ctx;
8494  #else
8495 -               
8496 +
8497                 buffer_free(srv_socket->srv_token);
8498                 free(srv_socket);
8499 -               
8500 +
8501                 buffer_free(b);
8502 -               
8503 -               log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", 
8504 +
8505 +               log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
8506                                 "ssl requested but openssl support is not compiled in");
8507 -               
8508 +
8509                 return -1;
8510  #endif
8511         } else {
8512 @@ -390,10 +393,10 @@
8513                 }
8514  #endif
8515         }
8516 -       
8517 +
8518         srv_socket->is_ssl = s->is_ssl;
8519         srv_socket->fde_ndx = -1;
8520 -       
8521 +
8522         if (srv->srv_sockets.size == 0) {
8523                 srv->srv_sockets.size = 4;
8524                 srv->srv_sockets.used = 0;
8525 @@ -402,11 +405,10 @@
8526                 srv->srv_sockets.size += 4;
8527                 srv->srv_sockets.ptr = realloc(srv->srv_sockets.ptr, srv->srv_sockets.size * sizeof(server_socket));
8528         }
8529 -       
8530 +
8531         srv->srv_sockets.ptr[srv->srv_sockets.used++] = srv_socket;
8532 -       
8533         buffer_free(b);
8534 -       
8535 +
8536         return 0;
8537  }
8538  
8539 @@ -414,45 +416,58 @@
8540         size_t i;
8541         for (i = 0; i < srv->srv_sockets.used; i++) {
8542                 server_socket *srv_socket = srv->srv_sockets.ptr[i];
8543 -               
8544 +
8545                 if (srv_socket->fd != -1) {
8546                         /* check if server fd are already registered */
8547                         if (srv_socket->fde_ndx != -1) {
8548                                 fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);
8549                                 fdevent_unregister(srv->ev, srv_socket->fd);
8550                         }
8551 -               
8552 +
8553                         close(srv_socket->fd);
8554                 }
8555 -               
8556 +
8557 +               if (srv_socket->is_ssl) {
8558 +#ifdef USE_OPENSSL
8559 +                       SSL_CTX_free(srv_socket->ssl_ctx);
8560 +#endif
8561 +               }
8562 +
8563                 buffer_free(srv_socket->srv_token);
8564 -               
8565 +
8566                 free(srv_socket);
8567         }
8568 -       
8569 +
8570 +#ifdef USE_OPENSSL
8571 +       ERR_free_strings();
8572 +#endif
8573         free(srv->srv_sockets.ptr);
8574 -       
8575 +
8576         return 0;
8577  }
8578  
8579  typedef enum {
8580         NETWORK_BACKEND_UNSET,
8581 +
8582         NETWORK_BACKEND_WRITE,
8583         NETWORK_BACKEND_WRITEV,
8584         NETWORK_BACKEND_LINUX_SENDFILE,
8585         NETWORK_BACKEND_FREEBSD_SENDFILE,
8586 -       NETWORK_BACKEND_SOLARIS_SENDFILEV
8587 +       NETWORK_BACKEND_SOLARIS_SENDFILEV,
8588 +
8589 +    NETWORK_BACKEND_WIN32_SEND,
8590 +    NETWORK_BACKEND_WIN32_TRANSMITFILE,
8591  } network_backend_t;
8592  
8593  int network_init(server *srv) {
8594         buffer *b;
8595         size_t i;
8596         network_backend_t backend;
8597 -       
8598 -       struct nb_map { 
8599 -               network_backend_t nb; 
8600 -               const char *name; 
8601 -       } network_backends[] = { 
8602 +
8603 +       struct nb_map {
8604 +               network_backend_t nb;
8605 +               const char *name;
8606 +       } network_backends[] = {
8607                 /* lowest id wins */
8608  #if defined USE_LINUX_SENDFILE
8609                 { NETWORK_BACKEND_LINUX_SENDFILE,       "linux-sendfile" },
8610 @@ -466,21 +481,30 @@
8611  #if defined USE_WRITEV
8612                 { NETWORK_BACKEND_WRITEV,               "writev" },
8613  #endif
8614 +#if defined USE_WRITE
8615                 { NETWORK_BACKEND_WRITE,                "write" },
8616 +#endif
8617 +#if defined USE_WIN32_TRANSMITFILE
8618 +               { NETWORK_BACKEND_WIN32_TRANSMITFILE,   "win32-transmitfile" },
8619 +#endif
8620 +#if defined USE_WIN32_SEND
8621 +               { NETWORK_BACKEND_WIN32_SEND,           "win32-send" },
8622 +#endif
8623 +
8624                 { NETWORK_BACKEND_UNSET,                NULL }
8625         };
8626 -       
8627 +
8628         b = buffer_init();
8629 -               
8630 +
8631         buffer_copy_string_buffer(b, srv->srvconf.bindhost);
8632         buffer_append_string(b, ":");
8633         buffer_append_long(b, srv->srvconf.port);
8634 -       
8635 +
8636         if (0 != network_server_init(srv, b, srv->config_storage[0])) {
8637                 return -1;
8638         }
8639         buffer_free(b);
8640 -               
8641 +
8642  #ifdef USE_OPENSSL
8643         srv->network_ssl_backend_write = network_write_chunkqueue_openssl;
8644  #endif
8645 @@ -500,54 +524,80 @@
8646                 if (NULL == network_backends[i].name) {
8647                         /* we don't know it */
8648  
8649 -                       log_error_write(srv, __FILE__, __LINE__, "sb", 
8650 -                                       "server.network-backend has a unknown value:", 
8651 +                       log_error_write(srv, __FILE__, __LINE__, "sb",
8652 +                                       "server.network-backend has a unknown value:",
8653                                         srv->srvconf.network_backend);
8654  
8655                         return -1;
8656                 }
8657         }
8658  
8659 +#define SET_NETWORK_BACKEND(read, write) \
8660 +    srv->network_backend_write = network_write_chunkqueue_##write;\
8661 +    srv->network_backend_read = network_read_chunkqueue_##read
8662 +
8663 +#define SET_NETWORK_BACKEND_SSL(read, write) \
8664 +    srv->network_ssl_backend_write = network_write_chunkqueue_##write;\
8665 +    srv->network_ssl_backend_read = network_read_chunkqueue_##read
8666 +
8667         switch(backend) {
8668 +
8669 +#ifdef USE_WIN32_SEND
8670 +       case NETWORK_BACKEND_WIN32_SEND:
8671 +        SET_NETWORK_BACKEND(win32recv, win32send);
8672 +               break;
8673 +#ifdef USE_WIN32_TRANSMITFILE
8674 +       case NETWORK_BACKEND_WIN32_TRANSMITFILE:
8675 +        SET_NETWORK_BACKEND(win32recv, win32transmitfile);
8676 +               break;
8677 +#endif
8678 +#endif
8679 +
8680 +#ifdef USE_WRITE
8681         case NETWORK_BACKEND_WRITE:
8682 -               srv->network_backend_write = network_write_chunkqueue_write;
8683 +        SET_NETWORK_BACKEND(read, write);
8684                 break;
8685 +
8686  #ifdef USE_WRITEV
8687         case NETWORK_BACKEND_WRITEV:
8688 -               srv->network_backend_write = network_write_chunkqueue_writev;
8689 +        SET_NETWORK_BACKEND(read, writev);
8690                 break;
8691  #endif
8692  #ifdef USE_LINUX_SENDFILE
8693         case NETWORK_BACKEND_LINUX_SENDFILE:
8694 -               srv->network_backend_write = network_write_chunkqueue_linuxsendfile; 
8695 +        SET_NETWORK_BACKEND(read, linuxsendfile);
8696                 break;
8697  #endif
8698  #ifdef USE_FREEBSD_SENDFILE
8699         case NETWORK_BACKEND_FREEBSD_SENDFILE:
8700 -               srv->network_backend_write = network_write_chunkqueue_freebsdsendfile; 
8701 +        SET_NETWORK_BACKEND(read, freebsdsendfile);
8702                 break;
8703  #endif
8704  #ifdef USE_SOLARIS_SENDFILEV
8705         case NETWORK_BACKEND_SOLARIS_SENDFILEV:
8706 -               srv->network_backend_write = network_write_chunkqueue_solarissendfilev; 
8707 +        SET_NETWORK_BACKEND(read, solarissendfilev);
8708                 break;
8709  #endif
8710 +#endif
8711         default:
8712                 return -1;
8713         }
8714 +#ifdef USE_OPENSSL
8715 +        SET_NETWORK_BACKEND_SSL(openssl, openssl);
8716 +#endif
8717  
8718         /* check for $SERVER["socket"] */
8719         for (i = 1; i < srv->config_context->used; i++) {
8720                 data_config *dc = (data_config *)srv->config_context->data[i];
8721                 specific_config *s = srv->config_storage[i];
8722                 size_t j;
8723 -               
8724 +
8725                 /* not our stage */
8726                 if (COMP_SERVER_SOCKET != dc->comp) continue;
8727 -               
8728 +
8729                 if (dc->cond != CONFIG_COND_EQ) {
8730                         log_error_write(srv, __FILE__, __LINE__, "s", "only == is allowed for $SERVER[\"socket\"].");
8731 -                       
8732 +
8733                         return -1;
8734                 }
8735  
8736 @@ -558,36 +608,47 @@
8737                                 break;
8738                         }
8739                 }
8740 -               
8741 +
8742                 if (j == srv->srv_sockets.used) {
8743                         if (0 != network_server_init(srv, dc->string, s)) return -1;
8744                 }
8745         }
8746 -       
8747 +
8748         return 0;
8749  }
8750  
8751  int network_register_fdevents(server *srv) {
8752         size_t i;
8753 -       
8754         if (-1 == fdevent_reset(srv->ev)) {
8755                 return -1;
8756         }
8757 -       
8758         /* register fdevents after reset */
8759         for (i = 0; i < srv->srv_sockets.used; i++) {
8760                 server_socket *srv_socket = srv->srv_sockets.ptr[i];
8761 -               
8762                 fdevent_register(srv->ev, srv_socket->fd, network_server_handle_fdevent, srv_socket);
8763                 fdevent_event_add(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN);
8764         }
8765         return 0;
8766  }
8767  
8768 -int network_write_chunkqueue(server *srv, connection *con, chunkqueue *cq) {
8769 -       int ret = -1;
8770 +network_status_t network_read_chunkqueue(server *srv, connection *con, chunkqueue *cq) {
8771 +    server_socket *srv_socket = con->srv_socket;
8772 +
8773 +       if (srv_socket->is_ssl) {
8774 +#ifdef USE_OPENSSL
8775 +               return srv->network_ssl_backend_read(srv, con, con->ssl, cq);
8776 +#else
8777 +               return NETWORK_STATUS_FATAL_ERROR;
8778 +#endif
8779 +       } else {
8780 +               return srv->network_backend_read(srv, con, con->fd, cq);
8781 +       }
8782 +}
8783 +
8784 +network_status_t network_write_chunkqueue(server *srv, connection *con, chunkqueue *cq) {
8785 +       network_status_t ret = NETWORK_STATUS_UNSET;
8786         off_t written = 0;
8787 -#ifdef TCP_CORK        
8788 +#ifdef TCP_CORK
8789         int corked = 0;
8790  #endif
8791         server_socket *srv_socket = con->srv_socket;
8792 @@ -600,11 +661,11 @@
8793                 joblist_append(srv, con);
8794  
8795                 return 1;
8796 -       }  
8797 +       }
8798  
8799         written = cq->bytes_out;
8800  
8801 -#ifdef TCP_CORK        
8802 +#ifdef TCP_CORK
8803         /* Linux: put a cork into the socket as we want to combine the write() calls
8804          * but only if we really have multiple chunks
8805          */
8806 @@ -613,7 +674,7 @@
8807                 setsockopt(con->fd, IPPROTO_TCP, TCP_CORK, &corked, sizeof(corked));
8808         }
8809  #endif
8810 -       
8811 +
8812         if (srv_socket->is_ssl) {
8813  #ifdef USE_OPENSSL
8814                 ret = srv->network_ssl_backend_write(srv, con, con->ssl, cq);
8815 @@ -621,12 +682,17 @@
8816         } else {
8817                 ret = srv->network_backend_write(srv, con, con->fd, cq);
8818         }
8819 -       
8820 -       if (ret >= 0) {
8821 +
8822 +    switch (ret) {
8823 +    case NETWORK_STATUS_WAIT_FOR_EVENT:
8824 +    case NETWORK_STATUS_SUCCESS:
8825                 chunkqueue_remove_finished_chunks(cq);
8826 -               ret = chunkqueue_is_empty(cq) ? 0 : 1;
8827 +
8828 +        break;
8829 +    default:
8830 +        break;
8831         }
8832 -       
8833 +
8834  #ifdef TCP_CORK
8835         if (corked) {
8836                 corked = 0;
8837 @@ -639,13 +705,13 @@
8838         con->bytes_written_cur_second += written;
8839  
8840         *(con->conf.global_bytes_per_second_cnt_ptr) += written;
8841 -       
8842 +
8843         if (con->conf.kbytes_per_second &&
8844             (con->bytes_written_cur_second > con->conf.kbytes_per_second * 1024)) {
8845                 /* we reached the traffic limit */
8846  
8847                 con->traffic_limit_reached = 1;
8848                 joblist_append(srv, con);
8849 -       }  
8850 +       }
8851         return ret;
8852  }
8853
8854 Property changes on: src/network.c
8855 ___________________________________________________________________
8856 Name: svn:eol-style
8857    + native
8858
8859 Index: src/network.h
8860 ===================================================================
8861 --- src/network.h       (.../tags/lighttpd-1.4.11)      (revision 1159)
8862 +++ src/network.h       (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
8863 @@ -3,7 +3,8 @@
8864  
8865  #include "server.h"
8866  
8867 -int network_write_chunkqueue(server *srv, connection *con, chunkqueue *c);
8868 +network_status_t network_write_chunkqueue(server *srv, connection *con, chunkqueue *c);
8869 +network_status_t network_read_chunkqueue(server *srv, connection *con, chunkqueue *c);
8870  
8871  int network_init(server *srv);
8872  int network_close(server *srv);
8873
8874 Property changes on: src/network.h
8875 ___________________________________________________________________
8876 Name: svn:eol-style
8877    + native
8878
8879 Index: src/fdevent_freebsd_kqueue.c
8880 ===================================================================
8881 --- src/fdevent_freebsd_kqueue.c        (.../tags/lighttpd-1.4.11)      (revision 1159)
8882 +++ src/fdevent_freebsd_kqueue.c        (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
8883 @@ -1,6 +1,5 @@
8884  #include <sys/types.h>
8885  
8886 -#include <unistd.h>
8887  #include <stdlib.h>
8888  #include <stdio.h>
8889  #include <string.h>
8890 @@ -48,7 +47,7 @@
8891  
8892                 return -1;
8893         }
8894 -       
8895 +
8896         return -1;
8897  }
8898  
8899 @@ -65,7 +64,7 @@
8900  
8901         ts.tv_sec  = 0;
8902         ts.tv_nsec = 0;
8903 -       
8904 +
8905         ret = kevent(ev->kq_fd,
8906                      &kev, 1,
8907                      NULL, 0,
8908 @@ -77,7 +76,7 @@
8909  
8910                 return -1;
8911         }
8912 -       
8913 +
8914         if (filter == EVFILT_READ) {
8915                 bitset_set_bit(ev->kq_bevents, fd);
8916         } else {
8917 @@ -124,7 +123,7 @@
8918         } else if (e == EVFILT_WRITE) {
8919                 events |= FDEVENT_OUT;
8920         }
8921 -       
8922 +
8923         e = ev->kq_results[ndx].flags;
8924  
8925         if (e & EV_EOF) {
8926 @@ -152,10 +151,10 @@
8927         if (-1 == (ev->kq_fd = kqueue())) {
8928                 fprintf(stderr, "%s.%d: kqueue failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n",
8929                         __FILE__, __LINE__, strerror(errno));
8930 -               
8931 +
8932                 return -1;
8933         }
8934 -       
8935 +
8936         return 0;
8937  }
8938  
8939 @@ -186,7 +185,7 @@
8940         if (-1 == (ev->kq_fd = kqueue())) {
8941                 fprintf(stderr, "%s.%d: kqueue failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n",
8942                         __FILE__, __LINE__, strerror(errno));
8943 -               
8944 +
8945                 return -1;
8946         }
8947  
8948
8949 Property changes on: src/fdevent_freebsd_kqueue.c
8950 ___________________________________________________________________
8951 Name: svn:eol-style
8952    + native
8953
8954 Index: src/configfile.c
8955 ===================================================================
8956 --- src/configfile.c    (.../tags/lighttpd-1.4.11)      (revision 1159)
8957 +++ src/configfile.c    (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
8958 @@ -2,7 +2,6 @@
8959  
8960  #include <stdlib.h>
8961  #include <fcntl.h>
8962 -#include <unistd.h>
8963  #include <errno.h>
8964  #include <string.h>
8965  #include <stdio.h>
8966 @@ -13,21 +12,24 @@
8967  #include "log.h"
8968  #include "stream.h"
8969  #include "plugin.h"
8970 -#ifdef USE_LICENSE
8971 -#include "license.h"
8972 -#endif
8973 -
8974  #include "configparser.h"
8975  #include "configfile.h"
8976  #include "proc_open.h"
8977  
8978 +#include "sys-files.h"
8979 +#include "sys-process.h"
8980  
8981 +#ifndef PATH_MAX
8982 +/* win32 */
8983 +#define PATH_MAX 64
8984 +#endif
8985 +
8986  static int config_insert(server *srv) {
8987         size_t i;
8988         int ret = 0;
8989         buffer *stat_cache_string;
8990 -       
8991 -       config_values_t cv[] = { 
8992 +
8993 +       config_values_t cv[] = {
8994                 { "server.bind",                 NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 0 */
8995                 { "server.errorlog",             NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 1 */
8996                 { "server.errorfile-prefix",     NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 2 */
8997 @@ -38,7 +40,7 @@
8998                 { "server.tag",                  NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },  /* 7 */
8999                 { "server.use-ipv6",             NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 8 */
9000                 { "server.modules",              NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_SERVER },       /* 9 */
9001 -               
9002 +
9003                 { "server.event-handler",        NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 10 */
9004                 { "server.pid-file",             NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 11 */
9005                 { "server.max-request-size",     NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },   /* 12 */
9006 @@ -49,7 +51,7 @@
9007                 { "server.max-keep-alive-requests", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 17 */
9008                 { "server.name",                 NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },  /* 18 */
9009                 { "server.max-keep-alive-idle",  NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },   /* 19 */
9010 -               
9011 +
9012                 { "server.max-read-idle",        NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },   /* 20 */
9013                 { "server.max-write-idle",       NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },   /* 21 */
9014                 { "server.error-handler-404",    NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },  /* 22 */
9015 @@ -60,19 +62,19 @@
9016                 { "mimetype.use-xattr",          NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 27 */
9017                 { "mimetype.assign",             NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },   /* 28 */
9018                 { "ssl.pemfile",                 NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 29 */
9019 -               
9020 +
9021                 { "ssl.engine",                  NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 30 */
9022 -               
9023 +
9024                 { "debug.log-file-not-found",    NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 31 */
9025                 { "debug.log-request-handling",  NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 32 */
9026                 { "debug.log-response-header",   NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 33 */
9027                 { "debug.log-request-header",    NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 34 */
9028 -               
9029 +
9030                 { "server.protocol-http11",      NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 35 */
9031                 { "debug.log-request-header-on-error", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 36 */
9032                 { "debug.log-state-handling",    NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 37 */
9033                 { "ssl.ca-file",                 NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 38 */
9034 -               
9035 +
9036                 { "server.errorlog-use-syslog",  NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 39 */
9037                 { "server.range-requests",       NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 40 */
9038                 { "server.stat-cache-engine",    NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },  /* 41 */
9039 @@ -80,7 +82,8 @@
9040                 { "server.network-backend",      NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },  /* 43 */
9041                 { "server.upload-dirs",          NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },   /* 44 */
9042                 { "server.core-files",           NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 45 */
9043 -               
9044 +               { "debug.log-condition-cache-handling", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },    /* 46 */
9045 +
9046                 { "server.host",                 "use server.bind instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
9047                 { "server.docroot",              "use server.document-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
9048                 { "server.virtual-root",         "load mod_simple_vhost and use simple-vhost.server-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
9049 @@ -90,11 +93,11 @@
9050                 { "server.groupid",              "use server.groupname instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
9051                 { "server.use-keep-alive",       "use server.max-keep-alive-requests = 0 instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
9052                 { "server.force-lower-case-files",       "use server.force-lowercase-filenames instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
9053 -               
9054 +
9055                 { NULL,                          NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
9056         };
9057  
9058 -       
9059 +
9060         /* 0 */
9061         cv[0].destination = srv->srvconf.bindhost;
9062         cv[1].destination = srv->srvconf.errorlog_file;
9063 @@ -102,33 +105,33 @@
9064         cv[4].destination = srv->srvconf.username;
9065         cv[5].destination = srv->srvconf.groupname;
9066         cv[6].destination = &(srv->srvconf.port);
9067 -       
9068 +
9069         cv[9].destination = srv->srvconf.modules;
9070         cv[10].destination = srv->srvconf.event_handler;
9071         cv[11].destination = srv->srvconf.pid_file;
9072 -       
9073 +
9074         cv[13].destination = &(srv->srvconf.max_worker);
9075         cv[23].destination = &(srv->srvconf.max_fds);
9076         cv[36].destination = &(srv->srvconf.log_request_header_on_error);
9077         cv[37].destination = &(srv->srvconf.log_state_handling);
9078 -       
9079 +
9080         cv[39].destination = &(srv->srvconf.errorlog_use_syslog);
9081 -       
9082 +
9083         stat_cache_string = buffer_init();
9084         cv[41].destination = stat_cache_string;
9085         cv[43].destination = srv->srvconf.network_backend;
9086         cv[44].destination = srv->srvconf.upload_tempdirs;
9087         cv[45].destination = &(srv->srvconf.enable_cores);
9088 -       
9089 +
9090         cv[42].destination = &(srv->srvconf.max_conns);
9091         cv[12].destination = &(srv->srvconf.max_request_size);
9092         srv->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
9093  
9094         assert(srv->config_storage);
9095 -       
9096 +
9097         for (i = 0; i < srv->config_context->used; i++) {
9098                 specific_config *s;
9099 -               
9100 +
9101                 s = calloc(1, sizeof(specific_config));
9102                 assert(s);
9103                 s->document_root = buffer_init();
9104 @@ -154,17 +157,18 @@
9105                 s->global_kbytes_per_second = 0;
9106                 s->global_bytes_per_second_cnt = 0;
9107                 s->global_bytes_per_second_cnt_ptr = &s->global_bytes_per_second_cnt;
9108 -               
9109 +
9110                 cv[2].destination = s->errorfile_prefix;
9111 -               
9112 +
9113                 cv[7].destination = s->server_tag;
9114                 cv[8].destination = &(s->use_ipv6);
9115 -               
9116 -               
9117 +
9118 +
9119                 /* 13 max-worker */
9120                 cv[14].destination = s->document_root;
9121                 cv[15].destination = &(s->force_lowercase_filenames);
9122                 cv[16].destination = &(s->log_condition_handling);
9123 +               cv[46].destination = &(s->log_condition_cache_handling);
9124                 cv[17].destination = &(s->max_keep_alive_requests);
9125                 cv[18].destination = s->server_name;
9126                 cv[19].destination = &(s->max_keep_alive_idle);
9127 @@ -179,23 +183,23 @@
9128                 cv[28].destination = s->mimetypes;
9129                 cv[29].destination = s->ssl_pemfile;
9130                 cv[30].destination = &(s->is_ssl);
9131 -               
9132 +
9133                 cv[31].destination = &(s->log_file_not_found);
9134                 cv[32].destination = &(s->log_request_handling);
9135                 cv[33].destination = &(s->log_response_header);
9136                 cv[34].destination = &(s->log_request_header);
9137 -               
9138 +
9139                 cv[35].destination = &(s->allow_http11);
9140                 cv[38].destination = s->ssl_ca_file;
9141                 cv[40].destination = &(s->range_requests);
9142 -               
9143 +
9144                 srv->config_storage[i] = s;
9145 -       
9146 +
9147                 if (0 != (ret = config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv))) {
9148                         break;
9149                 }
9150         }
9151 -       
9152 +
9153         if (buffer_is_empty(stat_cache_string)) {
9154                 srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_SIMPLE;
9155         } else if (buffer_is_equal_string(stat_cache_string, CONST_STR_LEN("simple"))) {
9156 @@ -205,22 +209,22 @@
9157         } else if (buffer_is_equal_string(stat_cache_string, CONST_STR_LEN("disable"))) {
9158                 srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_NONE;
9159         } else {
9160 -               log_error_write(srv, __FILE__, __LINE__, "sb", 
9161 +               log_error_write(srv, __FILE__, __LINE__, "sb",
9162                                 "server.stat-cache-engine can be one of \"disable\", \"simple\", \"fam\", but not:", stat_cache_string);
9163                 ret = HANDLER_ERROR;
9164         }
9165 -       
9166 +
9167         buffer_free(stat_cache_string);
9168 -       
9169 +
9170         return ret;
9171 -                                                                
9172 +
9173  }
9174  
9175 -
9176 -#define PATCH(x) con->conf.x = s->x
9177 +#define PATCH(x) \
9178 +       con->conf.x = s->x
9179  int config_setup_connection(server *srv, connection *con) {
9180         specific_config *s = srv->config_storage[0];
9181 -       
9182 +
9183         PATCH(allow_http11);
9184         PATCH(mimetypes);
9185         PATCH(document_root);
9186 @@ -236,20 +240,21 @@
9187         PATCH(kbytes_per_second);
9188         PATCH(global_kbytes_per_second);
9189         PATCH(global_bytes_per_second_cnt);
9190 -       
9191 +
9192         con->conf.global_bytes_per_second_cnt_ptr = &s->global_bytes_per_second_cnt;
9193         buffer_copy_string_buffer(con->server_name, s->server_name);
9194 -       
9195 +
9196         PATCH(log_request_header);
9197         PATCH(log_response_header);
9198         PATCH(log_request_handling);
9199         PATCH(log_condition_handling);
9200 +       PATCH(log_condition_cache_handling);
9201         PATCH(log_file_not_found);
9202 -       
9203 +
9204         PATCH(range_requests);
9205         PATCH(force_lowercase_filenames);
9206         PATCH(is_ssl);
9207 -       
9208 +
9209         PATCH(ssl_pemfile);
9210         PATCH(ssl_ca_file);
9211         return 0;
9212 @@ -257,22 +262,22 @@
9213  
9214  int config_patch_connection(server *srv, connection *con, comp_key_t comp) {
9215         size_t i, j;
9216 -       
9217 +
9218         /* skip the first, the global context */
9219         for (i = 1; i < srv->config_context->used; i++) {
9220                 data_config *dc = (data_config *)srv->config_context->data[i];
9221                 specific_config *s = srv->config_storage[i];
9222 -               
9223 +
9224                 /* not our stage */
9225                 if (comp != dc->comp) continue;
9226 -               
9227 +
9228                 /* condition didn't match */
9229                 if (!config_check_cond(srv, con, dc)) continue;
9230 -               
9231 +
9232                 /* merge config */
9233                 for (j = 0; j < dc->value->used; j++) {
9234                         data_unset *du = dc->value->data[j];
9235 -                       
9236 +
9237                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.document-root"))) {
9238                                 PATCH(document_root);
9239                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.range-requests"))) {
9240 @@ -315,11 +320,13 @@
9241                                 PATCH(log_response_header);
9242                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("debug.log-condition-handling"))) {
9243                                 PATCH(log_condition_handling);
9244 +                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("debug.log-condition-cache-handling"))) {
9245 +                               PATCH(log_condition_cache_handling);
9246                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("debug.log-file-not-found"))) {
9247                                 PATCH(log_file_not_found);
9248                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.protocol-http11"))) {
9249                                 PATCH(allow_http11);
9250 -                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.force-lowercase-filenames"))) {  
9251 +                       } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.force-lowercase-filenames"))) {
9252                                 PATCH(force_lowercase_filenames);
9253                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.kbytes-per-second"))) {
9254                                 PATCH(global_kbytes_per_second);
9255 @@ -328,7 +335,7 @@
9256                         }
9257                 }
9258         }
9259 -       
9260 +
9261         return 0;
9262  }
9263  #undef PATCH
9264 @@ -336,15 +343,15 @@
9265  typedef struct {
9266         int foo;
9267         int bar;
9268 -       
9269 +
9270         const buffer *source;
9271         const char *input;
9272         size_t offset;
9273         size_t size;
9274 -       
9275 +
9276         int line_pos;
9277         int line;
9278 -       
9279 +
9280         int in_key;
9281         int in_brace;
9282         int in_cond;
9283 @@ -362,7 +369,7 @@
9284         }
9285  
9286         if (0 != stream_open(&(t->s), t->file)) {
9287 -               log_error_write(srv, __FILE__, __LINE__, "sbss", 
9288 +               log_error_write(srv, __FILE__, __LINE__, "sbss",
9289                                 "opening configfile ", t->file, "failed:", strerror(errno));
9290                 buffer_free(t->file);
9291                 return -1;
9292 @@ -373,7 +380,7 @@
9293         t->size = t->s.size;
9294         t->line = 1;
9295         t->line_pos = 1;
9296 -       
9297 +
9298         t->in_key = 1;
9299         t->in_brace = 0;
9300         t->in_cond = 0;
9301 @@ -401,7 +408,7 @@
9302  static int config_skip_comment(tokenizer_t *t) {
9303         int i;
9304         assert(t->input[t->offset] == '#');
9305 -       for (i = 1; t->input[t->offset + i] && 
9306 +       for (i = 1; t->input[t->offset + i] &&
9307              (t->input[t->offset + i] != '\n' && t->input[t->offset + i] != '\r');
9308              i++);
9309         t->offset += i;
9310 @@ -411,44 +418,44 @@
9311  static int config_tokenizer(server *srv, tokenizer_t *t, int *token_id, buffer *token) {
9312         int tid = 0;
9313         size_t i;
9314 -       
9315 +
9316         for (tid = 0; tid == 0 && t->offset < t->size && t->input[t->offset] ; ) {
9317                 char c = t->input[t->offset];
9318                 const char *start = NULL;
9319 -               
9320 +
9321                 switch (c) {
9322 -               case '=': 
9323 +               case '=':
9324                         if (t->in_brace) {
9325                                 if (t->input[t->offset + 1] == '>') {
9326                                         t->offset += 2;
9327 -                                       
9328 +
9329                                         buffer_copy_string(token, "=>");
9330 -                                       
9331 +
9332                                         tid = TK_ARRAY_ASSIGN;
9333                                 } else {
9334 -                                       log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 
9335 +                                       log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
9336                                                         "source:", t->source,
9337 -                                                       "line:", t->line, "pos:", t->line_pos, 
9338 +                                                       "line:", t->line, "pos:", t->line_pos,
9339                                                         "use => for assignments in arrays");
9340                                         return -1;
9341                                 }
9342                         } else if (t->in_cond) {
9343                                 if (t->input[t->offset + 1] == '=') {
9344                                         t->offset += 2;
9345 -                                       
9346 +
9347                                         buffer_copy_string(token, "==");
9348 -                                       
9349 +
9350                                         tid = TK_EQ;
9351                                 } else if (t->input[t->offset + 1] == '~') {
9352                                         t->offset += 2;
9353 -                                       
9354 +
9355                                         buffer_copy_string(token, "=~");
9356 -                                       
9357 +
9358                                         tid = TK_MATCH;
9359                                 } else {
9360 -                                       log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 
9361 +                                       log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
9362                                                         "source:", t->source,
9363 -                                                       "line:", t->line, "pos:", t->line_pos, 
9364 +                                                       "line:", t->line, "pos:", t->line_pos,
9365                                                         "only =~ and == are allowed in the condition");
9366                                         return -1;
9367                                 }
9368 @@ -456,51 +463,51 @@
9369                                 t->in_cond = 0;
9370                         } else if (t->in_key) {
9371                                 tid = TK_ASSIGN;
9372 -                               
9373 +
9374                                 buffer_copy_string_len(token, t->input + t->offset, 1);
9375 -                               
9376 +
9377                                 t->offset++;
9378                                 t->line_pos++;
9379                         } else {
9380 -                               log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 
9381 +                               log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
9382                                                 "source:", t->source,
9383 -                                               "line:", t->line, "pos:", t->line_pos, 
9384 +                                               "line:", t->line, "pos:", t->line_pos,
9385                                                 "unexpected equal-sign: =");
9386                                 return -1;
9387                         }
9388 -                       
9389 +
9390                         break;
9391 -               case '!': 
9392 +               case '!':
9393                         if (t->in_cond) {
9394                                 if (t->input[t->offset + 1] == '=') {
9395                                         t->offset += 2;
9396 -                                       
9397 +
9398                                         buffer_copy_string(token, "!=");
9399 -                                       
9400 +
9401                                         tid = TK_NE;
9402                                 } else if (t->input[t->offset + 1] == '~') {
9403                                         t->offset += 2;
9404 -                                       
9405 +
9406                                         buffer_copy_string(token, "!~");
9407 -                                       
9408 +
9409                                         tid = TK_NOMATCH;
9410                                 } else {
9411 -                                       log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 
9412 +                                       log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
9413                                                         "source:", t->source,
9414 -                                                       "line:", t->line, "pos:", t->line_pos, 
9415 +                                                       "line:", t->line, "pos:", t->line_pos,
9416                                                         "only !~ and != are allowed in the condition");
9417                                         return -1;
9418                                 }
9419                                 t->in_key = 1;
9420                                 t->in_cond = 0;
9421                         } else {
9422 -                               log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 
9423 +                               log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
9424                                                 "source:", t->source,
9425 -                                               "line:", t->line, "pos:", t->line_pos, 
9426 +                                               "line:", t->line, "pos:", t->line_pos,
9427                                                 "unexpected exclamation-marks: !");
9428                                 return -1;
9429                         }
9430 -                       
9431 +
9432                         break;
9433                 case '\t':
9434                 case ' ':
9435 @@ -546,10 +553,10 @@
9436                 case ',':
9437                         if (t->in_brace > 0) {
9438                                 tid = TK_COMMA;
9439 -                               
9440 +
9441                                 buffer_copy_string(token, "(COMMA)");
9442                         }
9443 -                       
9444 +
9445                         t->offset++;
9446                         t->line_pos++;
9447                         break;
9448 @@ -557,70 +564,70 @@
9449                         /* search for the terminating " */
9450                         start = t->input + t->offset + 1;
9451                         buffer_copy_string(token, "");
9452 -                       
9453 +
9454                         for (i = 1; t->input[t->offset + i]; i++) {
9455                                 if (t->input[t->offset + i] == '\\' &&
9456                                     t->input[t->offset + i + 1] == '"') {
9457 -                                       
9458 +
9459                                         buffer_append_string_len(token, start, t->input + t->offset + i - start);
9460 -                                       
9461 +
9462                                         start = t->input + t->offset + i + 1;
9463 -                                       
9464 +
9465                                         /* skip the " */
9466                                         i++;
9467                                         continue;
9468                                 }
9469 -                               
9470 -                               
9471 +
9472 +
9473                                 if (t->input[t->offset + i] == '"') {
9474                                         tid = TK_STRING;
9475 -                               
9476 +
9477                                         buffer_append_string_len(token, start, t->input + t->offset + i - start);
9478 -                                       
9479 +
9480                                         break;
9481                                 }
9482                         }
9483  
9484                         if (t->input[t->offset + i] == '\0') {
9485                                 /* ERROR */
9486 -                               
9487 -                               log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 
9488 +
9489 +                               log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
9490                                                 "source:", t->source,
9491 -                                               "line:", t->line, "pos:", t->line_pos, 
9492 +                                               "line:", t->line, "pos:", t->line_pos,
9493                                                 "missing closing quote");
9494 -                               
9495 +
9496                                 return -1;
9497                         }
9498 -                       
9499 +
9500                         t->offset += i + 1;
9501                         t->line_pos += i + 1;
9502 -                       
9503 +
9504                         break;
9505                 case '(':
9506                         t->offset++;
9507                         t->in_brace++;
9508 -                               
9509 +
9510                         tid = TK_LPARAN;
9511 -                               
9512 +
9513                         buffer_copy_string(token, "(");
9514                         break;
9515                 case ')':
9516                         t->offset++;
9517                         t->in_brace--;
9518 -                               
9519 +
9520                         tid = TK_RPARAN;
9521 -                               
9522 +
9523                         buffer_copy_string(token, ")");
9524                         break;
9525                 case '$':
9526                         t->offset++;
9527 -                               
9528 +
9529                         tid = TK_DOLLAR;
9530                         t->in_cond = 1;
9531                         t->in_key = 0;
9532 -                               
9533 +
9534                         buffer_copy_string(token, "$");
9535 -                       
9536 +
9537                         break;
9538  
9539                 case '+':
9540 @@ -637,96 +644,88 @@
9541  
9542                 case '{':
9543                         t->offset++;
9544 -                               
9545 +
9546                         tid = TK_LCURLY;
9547 -                               
9548 +
9549                         buffer_copy_string(token, "{");
9550 -                       
9551 +
9552                         break;
9553 -                       
9554 +
9555                 case '}':
9556                         t->offset++;
9557 -                               
9558 +
9559                         tid = TK_RCURLY;
9560 -                               
9561 +
9562                         buffer_copy_string(token, "}");
9563 -                       
9564 +
9565                         break;
9566  
9567                 case '[':
9568                         t->offset++;
9569 -                               
9570 +
9571                         tid = TK_LBRACKET;
9572 -                               
9573 +
9574                         buffer_copy_string(token, "[");
9575 -                       
9576 +
9577                         break;
9578 -                       
9579 +
9580                 case ']':
9581                         t->offset++;
9582 -                               
9583 +
9584                         tid = TK_RBRACKET;
9585 -                               
9586 +
9587                         buffer_copy_string(token, "]");
9588 -                       
9589 +
9590                         break;
9591                 case '#':
9592                         t->line_pos += config_skip_comment(t);
9593 -                       
9594 +
9595                         break;
9596                 default:
9597                         if (t->in_cond) {
9598 -                               for (i = 0; t->input[t->offset + i] && 
9599 +                               for (i = 0; t->input[t->offset + i] &&
9600                                      (isalpha((unsigned char)t->input[t->offset + i])
9601                                       ); i++);
9602 -                               
9603 +
9604                                 if (i && t->input[t->offset + i]) {
9605                                         tid = TK_SRVVARNAME;
9606                                         buffer_copy_string_len(token, t->input + t->offset, i);
9607 -                                       
9608 +
9609                                         t->offset += i;
9610                                         t->line_pos += i;
9611                                 } else {
9612                                         /* ERROR */
9613 -                                       log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 
9614 +                                       log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
9615                                                         "source:", t->source,
9616 -                                                       "line:", t->line, "pos:", t->line_pos, 
9617 +                                                       "line:", t->line, "pos:", t->line_pos,
9618                                                         "invalid character in condition");
9619                                         return -1;
9620                                 }
9621                         } else if (isdigit((unsigned char)c)) {
9622                                 /* take all digits */
9623                                 for (i = 0; t->input[t->offset + i] && isdigit((unsigned char)t->input[t->offset + i]);  i++);
9624 -                               
9625 +
9626                                 /* was there it least a digit ? */
9627 -                               if (i && t->input[t->offset + i]) {
9628 +                               if (i) {
9629                                         tid = TK_INTEGER;
9630 -                                       
9631 +
9632                                         buffer_copy_string_len(token, t->input + t->offset, i);
9633 -                                       
9634 +
9635                                         t->offset += i;
9636                                         t->line_pos += i;
9637 -                               } else {
9638 -                                       /* ERROR */
9639 -                                       log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 
9640 -                                                       "source:", t->source,
9641 -                                                       "line:", t->line, "pos:", t->line_pos, 
9642 -                                                       "unexpected EOF");
9643 -                                       
9644 -                                       return -1;
9645                                 }
9646                         } else {
9647                                 /* the key might consist of [-.0-9a-z] */
9648 -                               for (i = 0; t->input[t->offset + i] && 
9649 -                                    (isalnum((unsigned char)t->input[t->offset + i]) || 
9650 +                               for (i = 0; t->input[t->offset + i] &&
9651 +                                    (isalnum((unsigned char)t->input[t->offset + i]) ||
9652                                       t->input[t->offset + i] == '.' ||
9653                                       t->input[t->offset + i] == '_' || /* for env.* */
9654                                       t->input[t->offset + i] == '-'
9655                                       ); i++);
9656 -                               
9657 +
9658                                 if (i && t->input[t->offset + i]) {
9659                                         buffer_copy_string_len(token, t->input + t->offset, i);
9660 -                                       
9661 +
9662                                         if (strcmp(token->ptr, "include") == 0) {
9663                                                 tid = TK_INCLUDE;
9664                                         } else if (strcmp(token->ptr, "include_shell") == 0) {
9665 @@ -738,14 +737,14 @@
9666                                         } else {
9667                                                 tid = TK_LKEY;
9668                                         }
9669 -                                       
9670 +
9671                                         t->offset += i;
9672                                         t->line_pos += i;
9673                                 } else {
9674                                         /* ERROR */
9675 -                                       log_error_write(srv, __FILE__, __LINE__, "sbsdsds", 
9676 +                                       log_error_write(srv, __FILE__, __LINE__, "sbsdsds",
9677                                                         "source:", t->source,
9678 -                                                       "line:", t->line, "pos:", t->line_pos, 
9679 +                                                       "line:", t->line, "pos:", t->line_pos,
9680                                                         "invalid character in variable name");
9681                                         return -1;
9682                                 }
9683 @@ -753,16 +752,16 @@
9684                         break;
9685                 }
9686         }
9687 -       
9688 +
9689         if (tid) {
9690                 *token_id = tid;
9691  #if 0
9692 -               log_error_write(srv, __FILE__, __LINE__, "sbsdsdbdd", 
9693 +               log_error_write(srv, __FILE__, __LINE__, "sbsdsdbdd",
9694                                 "source:", t->source,
9695                                 "line:", t->line, "pos:", t->line_pos,
9696                                 token, token->used - 1, tid);
9697  #endif
9698 -               
9699 +
9700                 return 1;
9701         } else if (t->offset < t->size) {
9702                 fprintf(stderr, "%s.%d: %d, %s\n",
9703 @@ -781,10 +780,11 @@
9704         pParser = configparserAlloc( malloc );
9705         lasttoken = buffer_init();
9706         token = buffer_init();
9707 +
9708         while((1 == (ret = config_tokenizer(srv, t, &token_id, token))) && context->ok) {
9709                 buffer_copy_string_buffer(lasttoken, token);
9710                 configparser(pParser, token_id, token, context);
9711 -               
9712 +
9713                 token = buffer_init();
9714         }
9715         buffer_free(token);
9716 @@ -797,14 +797,14 @@
9717                 }
9718         }
9719         configparserFree(pParser, free);
9720 -       
9721 +
9722         if (ret == -1) {
9723 -               log_error_write(srv, __FILE__, __LINE__, "sb", 
9724 +               log_error_write(srv, __FILE__, __LINE__, "sb",
9725                                 "configfile parser failed:", lasttoken);
9726         } else if (context->ok == 0) {
9727 -               log_error_write(srv, __FILE__, __LINE__, "sbsdsdsb", 
9728 +               log_error_write(srv, __FILE__, __LINE__, "sbsdsdsb",
9729                                 "source:", t->source,
9730 -                               "line:", t->line, "pos:", t->line_pos, 
9731 +                               "line:", t->line, "pos:", t->line_pos,
9732                                 "parser failed somehow near here:", lasttoken);
9733                 ret = -1;
9734         }
9735 @@ -821,7 +821,7 @@
9736         t->offset = 0;
9737         t->line = 1;
9738         t->line_pos = 1;
9739 -       
9740 +
9741         t->in_key = 1;
9742         t->in_brace = 0;
9743         t->in_cond = 0;
9744 @@ -844,7 +844,7 @@
9745         }
9746  
9747         if (0 != stream_open(&s, filename)) {
9748 -               log_error_write(srv, __FILE__, __LINE__, "sbss", 
9749 +               log_error_write(srv, __FILE__, __LINE__, "sbss",
9750                                 "opening configfile ", filename, "failed:", strerror(errno));
9751                 ret = -1;
9752         } else {
9753 @@ -866,7 +866,7 @@
9754         char oldpwd[PATH_MAX];
9755  
9756         if (NULL == getcwd(oldpwd, sizeof(oldpwd))) {
9757 -               log_error_write(srv, __FILE__, __LINE__, "s", 
9758 +               log_error_write(srv, __FILE__, __LINE__, "s",
9759                                 "cannot get cwd", strerror(errno));
9760                 return -1;
9761         }
9762 @@ -879,7 +879,7 @@
9763         }
9764  
9765         if (0 != proc_open_buffer(&proc, cmd, NULL, out, NULL)) {
9766 -               log_error_write(srv, __FILE__, __LINE__, "sbss", 
9767 +               log_error_write(srv, __FILE__, __LINE__, "sbss",
9768                                 "opening", source, "failed:", strerror(errno));
9769                 ret = -1;
9770         } else {
9771 @@ -896,13 +896,12 @@
9772  static void context_init(server *srv, config_t *context) {
9773         context->srv = srv;
9774         context->ok = 1;
9775 -       context->configs_stack = array_init();
9776 -       context->configs_stack->is_weakref = 1;
9777 +       context->configs_stack = buffer_ptr_init(NULL);
9778         context->basedir = buffer_init();
9779  }
9780  
9781  static void context_free(config_t *context) {
9782 -       array_free(context->configs_stack);
9783 +       buffer_ptr_free(context->configs_stack);
9784         buffer_free(context->basedir);
9785  }
9786  
9787 @@ -918,18 +917,15 @@
9788         context_init(srv, &context);
9789         context.all_configs = srv->config_context;
9790  
9791 -       pos = strrchr(fn,
9792 -#ifdef __WIN32
9793 -                       '\\'
9794 -#else
9795 -                       '/'
9796 -#endif
9797 -                       );
9798 +    /* use the current dir as basedir for all other includes
9799 +    */
9800 +       pos = strrchr(fn, DIR_SEPERATOR);
9801 +
9802         if (pos) {
9803                 buffer_copy_string_len(context.basedir, fn, pos - fn + 1);
9804                 fn = pos + 1;
9805         }
9806 -       
9807 +
9808         dc = data_config_init();
9809         buffer_copy_string(dc->key, "global");
9810  
9811 @@ -944,7 +940,7 @@
9812         dpid->value = getpid();
9813         buffer_copy_string(dpid->key, "var.PID");
9814         array_insert_unique(srv->config, (data_unset *)dpid);
9815 -       
9816 +
9817         dcwd = data_string_init();
9818         buffer_prepare_copy(dcwd->value, 1024);
9819         if (NULL != getcwd(dcwd->value->ptr, dcwd->value->size - 1)) {
9820 @@ -968,7 +964,7 @@
9821         } else {
9822                 return -1;
9823         }
9824 -       
9825 +
9826         if (NULL != (modules = (data_array *)array_get_element(srv->config, "server.modules"))) {
9827                 data_string *ds;
9828                 data_array *prepends;
9829 @@ -1026,22 +1022,23 @@
9830                 buffer_copy_string(modules->key, "server.modules");
9831                 array_insert_unique(srv->config, (data_unset *)modules);
9832         }
9833 -       
9834  
9835 +
9836         if (0 != config_insert(srv)) {
9837                 return -1;
9838         }
9839 -       
9840 +
9841         return 0;
9842  }
9843  
9844 +
9845  int config_set_defaults(server *srv) {
9846         size_t i;
9847         specific_config *s = srv->config_storage[0];
9848         struct stat st1, st2;
9849 -       
9850 -       struct ev_map { fdevent_handler_t et; const char *name; } event_handlers[] = 
9851 -       { 
9852 +
9853 +       struct ev_map { fdevent_handler_t et; const char *name; } event_handlers[] =
9854 +       {
9855                 /* - poll is most reliable
9856                  * - select works everywhere
9857                  * - linux-* are experimental
9858 @@ -1067,20 +1064,21 @@
9859  #endif
9860                 { FDEVENT_HANDLER_UNSET,          NULL }
9861         };
9862 -       
9863  
9864 -       if (buffer_is_empty(s->document_root)) {  
9865 -               log_error_write(srv, __FILE__, __LINE__, "s",  
9866 -                               "a default document-root has to be set");  
9867 -               
9868 -               return -1;  
9869 -       }  
9870 -       
9871 +
9872 +       if (buffer_is_empty(s->document_root)) {
9873 +               log_error_write(srv, __FILE__, __LINE__, "s",
9874 +                               "a default document-root has to be set");
9875 +
9876 +               return -1;
9877 +       }
9878 +
9879         if (buffer_is_empty(srv->srvconf.changeroot)) {
9880 -               if (-1 == stat(s->document_root->ptr, &st1)) {  
9881 -                       log_error_write(srv, __FILE__, __LINE__, "sb",  
9882 +        pathname_unix2local(s->document_root);
9883 +               if (-1 == stat(s->document_root->ptr, &st1)) {
9884 +                       log_error_write(srv, __FILE__, __LINE__, "sbs",
9885                                         "base-docroot doesn't exist:",
9886 -                                       s->document_root);  
9887 +                                       s->document_root, strerror(errno));
9888                         return -1;
9889                 }
9890  
9891 @@ -1088,87 +1086,87 @@
9892                 buffer_copy_string_buffer(srv->tmp_buf, srv->srvconf.changeroot);
9893                 buffer_append_string_buffer(srv->tmp_buf, s->document_root);
9894  
9895 -               if (-1 == stat(srv->tmp_buf->ptr, &st1)) {  
9896 -                       log_error_write(srv, __FILE__, __LINE__, "sb",  
9897 +               if (-1 == stat(srv->tmp_buf->ptr, &st1)) {
9898 +                       log_error_write(srv, __FILE__, __LINE__, "sb",
9899                                         "base-docroot doesn't exist:",
9900 -                                       srv->tmp_buf);  
9901 +                                       srv->tmp_buf);
9902                         return -1;
9903                 }
9904 -               
9905 +
9906         }
9907 -       
9908 -       buffer_copy_string_buffer(srv->tmp_buf, s->document_root);  
9909  
9910 -       buffer_to_lower(srv->tmp_buf);  
9911 +       buffer_copy_string_buffer(srv->tmp_buf, s->document_root);
9912  
9913 +       buffer_to_lower(srv->tmp_buf);
9914 +
9915         if (0 == stat(srv->tmp_buf->ptr, &st1)) {
9916                 int is_lower = 0;
9917  
9918                 is_lower = buffer_is_equal(srv->tmp_buf, s->document_root);
9919  
9920                 /* lower-case existed, check upper-case */
9921 -               buffer_copy_string_buffer(srv->tmp_buf, s->document_root);  
9922 +               buffer_copy_string_buffer(srv->tmp_buf, s->document_root);
9923  
9924 -               buffer_to_upper(srv->tmp_buf);  
9925 +               buffer_to_upper(srv->tmp_buf);
9926  
9927                 /* we have to handle the special case that upper and lower-casing results in the same filename
9928                  * as in server.document-root = "/" or "/12345/" */
9929  
9930                 if (is_lower && buffer_is_equal(srv->tmp_buf, s->document_root)) {
9931 -                       /* lower-casing and upper-casing didn't result in  
9932 -                        * an other filename, no need to stat(), 
9933 +                       /* lower-casing and upper-casing didn't result in
9934 +                        * an other filename, no need to stat(),
9935                          * just assume it is case-sensitive. */
9936  
9937                         s->force_lowercase_filenames = 0;
9938 -               } else if (0 == stat(srv->tmp_buf->ptr, &st2)) {  
9939 +               } else if (0 == stat(srv->tmp_buf->ptr, &st2)) {
9940  
9941 -                       /* upper case exists too, doesn't the FS handle this ? */  
9942 -                       
9943 -                       /* upper and lower have the same inode -> case-insensitve FS */  
9944 -                       
9945 -                       if (st1.st_ino == st2.st_ino) {  
9946 -                               /* upper and lower have the same inode -> case-insensitve FS */  
9947 -                               
9948 -                               s->force_lowercase_filenames = 1;  
9949 -                       }  
9950 -               }  
9951 -       }  
9952 -       
9953 +                       /* upper case exists too, doesn't the FS handle this ? */
9954 +
9955 +                       /* upper and lower have the same inode -> case-insensitve FS */
9956 +
9957 +                       if (st1.st_ino == st2.st_ino) {
9958 +                               /* upper and lower have the same inode -> case-insensitve FS */
9959 +
9960 +                               s->force_lowercase_filenames = 1;
9961 +                       }
9962 +               }
9963 +       }
9964 +
9965         if (srv->srvconf.port == 0) {
9966                 srv->srvconf.port = s->is_ssl ? 443 : 80;
9967         }
9968 -       
9969 +
9970         if (srv->srvconf.event_handler->used == 0) {
9971                 /* choose a good default
9972 -                * 
9973 -                * the event_handler list is sorted by 'goodness' 
9974 +                *
9975 +                * the event_handler list is sorted by 'goodness'
9976                  * taking the first available should be the best solution
9977                  */
9978                 srv->event_handler = event_handlers[0].et;
9979 -               
9980 +
9981                 if (FDEVENT_HANDLER_UNSET == srv->event_handler) {
9982 -                       log_error_write(srv, __FILE__, __LINE__, "s", 
9983 +                       log_error_write(srv, __FILE__, __LINE__, "s",
9984                                         "sorry, there is no event handler for this system");
9985 -                       
9986 +
9987                         return -1;
9988                 }
9989         } else {
9990                 /*
9991                  * User override
9992                  */
9993 -               
9994 +
9995                 for (i = 0; event_handlers[i].name; i++) {
9996                         if (0 == strcmp(event_handlers[i].name, srv->srvconf.event_handler->ptr)) {
9997                                 srv->event_handler = event_handlers[i].et;
9998                                 break;
9999                         }
10000                 }
10001 -               
10002 +
10003                 if (FDEVENT_HANDLER_UNSET == srv->event_handler) {
10004 -                       log_error_write(srv, __FILE__, __LINE__, "sb", 
10005 -                                       "the selected event-handler in unknown or not supported:", 
10006 +                       log_error_write(srv, __FILE__, __LINE__, "sb",
10007 +                                       "the selected event-handler in unknown or not supported:",
10008                                         srv->srvconf.event_handler );
10009 -                       
10010 +
10011                         return -1;
10012                 }
10013         }
10014 @@ -1176,19 +1174,19 @@
10015         if (s->is_ssl) {
10016                 if (buffer_is_empty(s->ssl_pemfile)) {
10017                         /* PEM file is require */
10018 -                       
10019 -                       log_error_write(srv, __FILE__, __LINE__, "s", 
10020 +
10021 +                       log_error_write(srv, __FILE__, __LINE__, "s",
10022                                         "ssl.pemfile has to be set");
10023                         return -1;
10024                 }
10025 -               
10026 +
10027  #ifndef USE_OPENSSL
10028 -               log_error_write(srv, __FILE__, __LINE__, "s", 
10029 +               log_error_write(srv, __FILE__, __LINE__, "s",
10030                                 "ssl support is missing, recompile with --with-openssl");
10031 -               
10032 +
10033                 return -1;
10034  #endif
10035         }
10036 -       
10037 +
10038         return 0;
10039  }
10040
10041 Property changes on: src/configfile.c
10042 ___________________________________________________________________
10043 Name: svn:eol-style
10044    + native
10045
10046 Index: src/mod_trigger_b4_dl.c
10047 ===================================================================
10048 --- src/mod_trigger_b4_dl.c     (.../tags/lighttpd-1.4.11)      (revision 1159)
10049 +++ src/mod_trigger_b4_dl.c     (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
10050 @@ -24,18 +24,18 @@
10051  
10052  /**
10053   * this is a trigger_b4_dl for a lighttpd plugin
10054 - * 
10055 + *
10056   */
10057  
10058  /* plugin config for all request/connections */
10059  
10060  typedef struct {
10061         buffer *db_filename;
10062 -       
10063 +
10064         buffer *trigger_url;
10065         buffer *download_url;
10066         buffer *deny_url;
10067 -       
10068 +
10069         array  *mc_hosts;
10070         buffer *mc_namespace;
10071  #if defined(HAVE_PCRE_H)
10072 @@ -46,58 +46,58 @@
10073         GDBM_FILE db;
10074  #endif
10075  
10076 -#if defined(HAVE_MEMCACHE_H) 
10077 +#if defined(HAVE_MEMCACHE_H)
10078         struct memcache *mc;
10079  #endif
10080 -       
10081 +
10082         unsigned short trigger_timeout;
10083         unsigned short debug;
10084  } plugin_config;
10085  
10086  typedef struct {
10087         PLUGIN_DATA;
10088 -       
10089 +
10090         buffer *tmp_buf;
10091 -       
10092 +
10093         plugin_config **config_storage;
10094 -       
10095 -       plugin_config conf; 
10096 +
10097 +       plugin_config conf;
10098  } plugin_data;
10099  
10100  /* init the plugin data */
10101  INIT_FUNC(mod_trigger_b4_dl_init) {
10102         plugin_data *p;
10103 -       
10104 +
10105         p = calloc(1, sizeof(*p));
10106 -       
10107 +
10108         p->tmp_buf = buffer_init();
10109 -       
10110 +
10111         return p;
10112  }
10113  
10114  /* detroy the plugin data */
10115  FREE_FUNC(mod_trigger_b4_dl_free) {
10116         plugin_data *p = p_d;
10117 -       
10118 +
10119         UNUSED(srv);
10120  
10121         if (!p) return HANDLER_GO_ON;
10122 -       
10123 +
10124         if (p->config_storage) {
10125                 size_t i;
10126                 for (i = 0; i < srv->config_context->used; i++) {
10127                         plugin_config *s = p->config_storage[i];
10128  
10129                         if (!s) continue;
10130 -                       
10131 +
10132                         buffer_free(s->db_filename);
10133                         buffer_free(s->download_url);
10134                         buffer_free(s->trigger_url);
10135                         buffer_free(s->deny_url);
10136 -                       
10137 +
10138                         buffer_free(s->mc_namespace);
10139                         array_free(s->mc_hosts);
10140 -                       
10141 +
10142  #if defined(HAVE_PCRE_H)
10143                         if (s->trigger_regex) pcre_free(s->trigger_regex);
10144                         if (s->download_regex) pcre_free(s->download_regex);
10145 @@ -108,16 +108,16 @@
10146  #if defined(HAVE_MEMCACHE_H)
10147                         if (s->mc) mc_free(s->mc);
10148  #endif
10149 -                       
10150 +
10151                         free(s);
10152                 }
10153                 free(p->config_storage);
10154         }
10155 -       
10156 +
10157         buffer_free(p->tmp_buf);
10158 -       
10159 +
10160         free(p);
10161 -       
10162 +
10163         return HANDLER_GO_ON;
10164  }
10165  
10166 @@ -126,9 +126,9 @@
10167  SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) {
10168         plugin_data *p = p_d;
10169         size_t i = 0;
10170 -       
10171 -       
10172 -       config_values_t cv[] = { 
10173 +
10174 +
10175 +       config_values_t cv[] = {
10176                 { "trigger-before-download.gdbm-filename",   NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
10177                 { "trigger-before-download.trigger-url",     NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
10178                 { "trigger-before-download.download-url",    NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 2 */
10179 @@ -139,18 +139,18 @@
10180                 { "trigger-before-download.debug",           NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },      /* 7 */
10181                 { NULL,                        NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
10182         };
10183 -       
10184 +
10185         if (!p) return HANDLER_ERROR;
10186 -       
10187 +
10188         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
10189 -       
10190 +
10191         for (i = 0; i < srv->config_context->used; i++) {
10192                 plugin_config *s;
10193  #if defined(HAVE_PCRE_H)
10194                 const char *errptr;
10195                 int erroff;
10196  #endif
10197 -               
10198 +
10199                 s = calloc(1, sizeof(plugin_config));
10200                 s->db_filename    = buffer_init();
10201                 s->download_url   = buffer_init();
10202 @@ -158,7 +158,7 @@
10203                 s->deny_url       = buffer_init();
10204                 s->mc_hosts       = array_init();
10205                 s->mc_namespace   = buffer_init();
10206 -               
10207 +
10208                 cv[0].destination = s->db_filename;
10209                 cv[1].destination = s->trigger_url;
10210                 cv[2].destination = s->download_url;
10211 @@ -167,41 +167,41 @@
10212                 cv[5].destination = s->mc_hosts;
10213                 cv[6].destination = s->mc_namespace;
10214                 cv[7].destination = &(s->debug);
10215 -               
10216 +
10217                 p->config_storage[i] = s;
10218 -       
10219 +
10220                 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
10221                         return HANDLER_ERROR;
10222                 }
10223  #if defined(HAVE_GDBM_H)
10224                 if (!buffer_is_empty(s->db_filename)) {
10225                         if (NULL == (s->db = gdbm_open(s->db_filename->ptr, 4096, GDBM_WRCREAT | GDBM_NOLOCK, S_IRUSR | S_IWUSR, 0))) {
10226 -                               log_error_write(srv, __FILE__, __LINE__, "s", 
10227 +                               log_error_write(srv, __FILE__, __LINE__, "s",
10228                                                 "gdbm-open failed");
10229                                 return HANDLER_ERROR;
10230                         }
10231                 }
10232  #endif
10233 -#if defined(HAVE_PCRE_H)               
10234 +#if defined(HAVE_PCRE_H)
10235                 if (!buffer_is_empty(s->download_url)) {
10236                         if (NULL == (s->download_regex = pcre_compile(s->download_url->ptr,
10237                                                                       0, &errptr, &erroff, NULL))) {
10238 -                               
10239 -                               log_error_write(srv, __FILE__, __LINE__, "sbss", 
10240 -                                               "compiling regex for download-url failed:", 
10241 +
10242 +                               log_error_write(srv, __FILE__, __LINE__, "sbss",
10243 +                                               "compiling regex for download-url failed:",
10244                                                 s->download_url, "pos:", erroff);
10245                                 return HANDLER_ERROR;
10246                         }
10247                 }
10248 -               
10249 +
10250                 if (!buffer_is_empty(s->trigger_url)) {
10251                         if (NULL == (s->trigger_regex = pcre_compile(s->trigger_url->ptr,
10252                                                                      0, &errptr, &erroff, NULL))) {
10253 -                               
10254 -                               log_error_write(srv, __FILE__, __LINE__, "sbss", 
10255 -                                               "compiling regex for trigger-url failed:", 
10256 +
10257 +                               log_error_write(srv, __FILE__, __LINE__, "sbss",
10258 +                                               "compiling regex for trigger-url failed:",
10259                                                 s->trigger_url, "pos:", erroff);
10260 -                               
10261 +
10262                                 return HANDLER_ERROR;
10263                         }
10264                 }
10265 @@ -211,100 +211,97 @@
10266  #if defined(HAVE_MEMCACHE_H)
10267                         size_t k;
10268                         s->mc = mc_new();
10269 -               
10270 +
10271                         for (k = 0; k < s->mc_hosts->used; k++) {
10272                                 data_string *ds = (data_string *)s->mc_hosts->data[k];
10273 -                               
10274 +
10275                                 if (0 != mc_server_add4(s->mc, ds->value->ptr)) {
10276 -                                       log_error_write(srv, __FILE__, __LINE__, "sb", 
10277 -                                                       "connection to host failed:", 
10278 +                                       log_error_write(srv, __FILE__, __LINE__, "sb",
10279 +                                                       "connection to host failed:",
10280                                                         ds->value);
10281 -                                       
10282 +
10283                                         return HANDLER_ERROR;
10284                                 }
10285                         }
10286  #else
10287 -                       log_error_write(srv, __FILE__, __LINE__, "s", 
10288 +                       log_error_write(srv, __FILE__, __LINE__, "s",
10289                                         "memcache support is not compiled in but trigger-before-download.memcache-hosts is set, aborting");
10290                         return HANDLER_ERROR;
10291  #endif
10292                 }
10293 -               
10294  
10295 +
10296  #if (!defined(HAVE_GDBM_H) && !defined(HAVE_MEMCACHE_H)) || !defined(HAVE_PCRE_H)
10297 -               log_error_write(srv, __FILE__, __LINE__, "s", 
10298 +               log_error_write(srv, __FILE__, __LINE__, "s",
10299                                 "(either gdbm or libmemcache) and pcre are require, but were not found, aborting");
10300                 return HANDLER_ERROR;
10301  #endif
10302         }
10303 -       
10304 +
10305         return HANDLER_GO_ON;
10306  }
10307  
10308 -#define PATCH(x) \
10309 -       p->conf.x = s->x;
10310  static int mod_trigger_b4_dl_patch_connection(server *srv, connection *con, plugin_data *p) {
10311         size_t i, j;
10312         plugin_config *s = p->config_storage[0];
10313 -       
10314 +
10315  #if defined(HAVE_GDBM)
10316 -       PATCH(db);
10317 -#endif 
10318 +       PATCH_OPTION(db);
10319 +#endif
10320  #if defined(HAVE_PCRE_H)
10321 -       PATCH(download_regex);
10322 -       PATCH(trigger_regex);
10323 -#endif 
10324 -       PATCH(trigger_timeout);
10325 -       PATCH(deny_url);
10326 -       PATCH(mc_namespace);
10327 -       PATCH(debug);
10328 +       PATCH_OPTION(download_regex);
10329 +       PATCH_OPTION(trigger_regex);
10330 +#endif
10331 +       PATCH_OPTION(trigger_timeout);
10332 +       PATCH_OPTION(deny_url);
10333 +       PATCH_OPTION(mc_namespace);
10334 +       PATCH_OPTION(debug);
10335  #if defined(HAVE_MEMCACHE_H)
10336 -       PATCH(mc);
10337 +       PATCH_OPTION(mc);
10338  #endif
10339 -       
10340 +
10341         /* skip the first, the global context */
10342         for (i = 1; i < srv->config_context->used; i++) {
10343                 data_config *dc = (data_config *)srv->config_context->data[i];
10344                 s = p->config_storage[i];
10345 -               
10346 +
10347                 /* condition didn't match */
10348                 if (!config_check_cond(srv, con, dc)) continue;
10349 -               
10350 +
10351                 /* merge config */
10352                 for (j = 0; j < dc->value->used; j++) {
10353                         data_unset *du = dc->value->data[j];
10354  
10355                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.download-url"))) {
10356  #if defined(HAVE_PCRE_H)
10357 -                               PATCH(download_regex);
10358 +                               PATCH_OPTION(download_regex);
10359  #endif
10360                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.trigger-url"))) {
10361  # if defined(HAVE_PCRE_H)
10362 -                               PATCH(trigger_regex);
10363 +                               PATCH_OPTION(trigger_regex);
10364  # endif
10365                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.gdbm-filename"))) {
10366  #if defined(HAVE_GDBM_H)
10367 -                               PATCH(db);
10368 +                               PATCH_OPTION(db);
10369  #endif
10370                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.trigger-timeout"))) {
10371 -                               PATCH(trigger_timeout);
10372 +                               PATCH_OPTION(trigger_timeout);
10373                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.debug"))) {
10374 -                               PATCH(debug);
10375 +                               PATCH_OPTION(debug);
10376                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.deny-url"))) {
10377 -                               PATCH(deny_url);
10378 +                               PATCH_OPTION(deny_url);
10379                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.memcache-namespace"))) {
10380 -                               PATCH(mc_namespace);
10381 +                               PATCH_OPTION(mc_namespace);
10382                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.memcache-hosts"))) {
10383  #if defined(HAVE_MEMCACHE_H)
10384 -                               PATCH(mc);
10385 +                               PATCH_OPTION(mc);
10386  #endif
10387                         }
10388                 }
10389         }
10390 -       
10391 +
10392         return 0;
10393  }
10394 -#undef PATCH
10395  
10396  URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
10397         plugin_data *p = p_d;
10398 @@ -315,20 +312,20 @@
10399         int n;
10400  # define N 10
10401         int ovec[N * 3];
10402 -       
10403 +
10404         if (con->uri.path->used == 0) return HANDLER_GO_ON;
10405 -       
10406 +
10407         mod_trigger_b4_dl_patch_connection(srv, con, p);
10408 -       
10409 +
10410         if (!p->conf.trigger_regex || !p->conf.download_regex) return HANDLER_GO_ON;
10411 -       
10412 +
10413  # if !defined(HAVE_GDBM_H) && !defined(HAVE_MEMCACHE_H)
10414         return HANDLER_GO_ON;
10415  # elif defined(HAVE_GDBM_H) && defined(HAVE_MEMCACHE_H)
10416         if (!p->conf.db && !p->conf.mc) return HANDLER_GO_ON;
10417         if (p->conf.db && p->conf.mc) {
10418                 /* can't decide which one */
10419 -               
10420 +
10421                 return HANDLER_GO_ON;
10422         }
10423  # elif defined(HAVE_GDBM_H)
10424 @@ -336,12 +333,12 @@
10425  # else
10426         if (!p->conf.mc) return HANDLER_GO_ON;
10427  # endif
10428 -       
10429 +
10430         if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "X-Forwarded-For"))) {
10431                 /* X-Forwarded-For contains the ip behind the proxy */
10432 -               
10433 +
10434                 remote_ip = ds->value->ptr;
10435 -               
10436 +
10437                 /* memcache can't handle spaces */
10438         } else {
10439                 remote_ip = inet_ntop_cache_get_ip(srv, &(con->dst_addr));
10440 @@ -350,13 +347,13 @@
10441         if (p->conf.debug) {
10442                 log_error_write(srv, __FILE__, __LINE__, "ss", "(debug) remote-ip:", remote_ip);
10443         }
10444 -               
10445 +
10446         /* check if URL is a trigger -> insert IP into DB */
10447         if ((n = pcre_exec(p->conf.trigger_regex, NULL, con->uri.path->ptr, con->uri.path->used - 1, 0, 0, ovec, 3 * N)) < 0) {
10448                 if (n != PCRE_ERROR_NOMATCH) {
10449                         log_error_write(srv, __FILE__, __LINE__, "sd",
10450                                         "execution error while matching:", n);
10451 -                       
10452 +
10453                         return HANDLER_ERROR;
10454                 }
10455         } else {
10456 @@ -364,34 +361,34 @@
10457                 if (p->conf.db) {
10458                         /* the trigger matched */
10459                         datum key, val;
10460 -                       
10461 +
10462                         key.dptr = (char *)remote_ip;
10463                         key.dsize = strlen(remote_ip);
10464 -                       
10465 +
10466                         val.dptr = (char *)&(srv->cur_ts);
10467                         val.dsize = sizeof(srv->cur_ts);
10468 -                       
10469 +
10470                         if (0 != gdbm_store(p->conf.db, key, val, GDBM_REPLACE)) {
10471                                 log_error_write(srv, __FILE__, __LINE__, "s",
10472                                                 "insert failed");
10473                         }
10474                 }
10475  # endif
10476 -# if defined(HAVE_MEMCACHE_H)          
10477 +# if defined(HAVE_MEMCACHE_H)
10478                 if (p->conf.mc) {
10479                         size_t i;
10480                         buffer_copy_string_buffer(p->tmp_buf, p->conf.mc_namespace);
10481                         buffer_append_string(p->tmp_buf, remote_ip);
10482 -                       
10483 +
10484                         for (i = 0; i < p->tmp_buf->used - 1; i++) {
10485                                 if (p->tmp_buf->ptr[i] == ' ') p->tmp_buf->ptr[i] = '-';
10486                         }
10487 -                       
10488 +
10489                         if (p->conf.debug) {
10490                                 log_error_write(srv, __FILE__, __LINE__, "sb", "(debug) triggered IP:", p->tmp_buf);
10491                         }
10492  
10493 -                       if (0 != mc_set(p->conf.mc, 
10494 +                       if (0 != mc_set(p->conf.mc,
10495                                         CONST_BUF_LEN(p->tmp_buf),
10496                                         (char *)&(srv->cur_ts), sizeof(srv->cur_ts),
10497                                         p->conf.trigger_timeout, 0)) {
10498 @@ -401,7 +398,7 @@
10499                 }
10500  # endif
10501         }
10502 -               
10503 +
10504         /* check if URL is a download -> check IP in DB, update timestamp */
10505         if ((n = pcre_exec(p->conf.download_regex, NULL, con->uri.path->ptr, con->uri.path->used - 1, 0, 0, ovec, 3 * N)) < 0) {
10506                 if (n != PCRE_ERROR_NOMATCH) {
10507 @@ -411,93 +408,93 @@
10508                 }
10509         } else {
10510                 /* the download uri matched */
10511 -# if defined(HAVE_GDBM_H)              
10512 +# if defined(HAVE_GDBM_H)
10513                 if (p->conf.db) {
10514                         datum key, val;
10515                         time_t last_hit;
10516 -               
10517 +
10518                         key.dptr = (char *)remote_ip;
10519                         key.dsize = strlen(remote_ip);
10520 -                       
10521 +
10522                         val = gdbm_fetch(p->conf.db, key);
10523 -               
10524 +
10525                         if (val.dptr == NULL) {
10526                                 /* not found, redirect */
10527 -                               
10528 +
10529                                 response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->conf.deny_url));
10530 -                               
10531 +
10532                                 con->http_status = 307;
10533 -                               
10534 +
10535                                 return HANDLER_FINISHED;
10536                         }
10537 -                       
10538 +
10539                         last_hit = *(time_t *)(val.dptr);
10540 -                       
10541 +
10542                         free(val.dptr);
10543 -                       
10544 +
10545                         if (srv->cur_ts - last_hit > p->conf.trigger_timeout) {
10546                                 /* found, but timeout, redirect */
10547 -                               
10548 +
10549                                 response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->conf.deny_url));
10550                                 con->http_status = 307;
10551 -                               
10552 +
10553                                 if (p->conf.db) {
10554                                         if (0 != gdbm_delete(p->conf.db, key)) {
10555                                                 log_error_write(srv, __FILE__, __LINE__, "s",
10556                                                                 "delete failed");
10557                                         }
10558                                 }
10559 -                               
10560 +
10561                                 return HANDLER_FINISHED;
10562                         }
10563 -                       
10564 +
10565                         val.dptr = (char *)&(srv->cur_ts);
10566                         val.dsize = sizeof(srv->cur_ts);
10567 -                       
10568 +
10569                         if (0 != gdbm_store(p->conf.db, key, val, GDBM_REPLACE)) {
10570                                 log_error_write(srv, __FILE__, __LINE__, "s",
10571                                                 "insert failed");
10572                         }
10573                 }
10574  # endif
10575 -               
10576 -# if defined(HAVE_MEMCACHE_H)          
10577 +
10578 +# if defined(HAVE_MEMCACHE_H)
10579                 if (p->conf.mc) {
10580                         void *r;
10581                         size_t i;
10582 -                       
10583 +
10584                         buffer_copy_string_buffer(p->tmp_buf, p->conf.mc_namespace);
10585                         buffer_append_string(p->tmp_buf, remote_ip);
10586 -                       
10587 +
10588                         for (i = 0; i < p->tmp_buf->used - 1; i++) {
10589                                 if (p->tmp_buf->ptr[i] == ' ') p->tmp_buf->ptr[i] = '-';
10590                         }
10591 -                       
10592 +
10593                         if (p->conf.debug) {
10594                                 log_error_write(srv, __FILE__, __LINE__, "sb", "(debug) checking IP:", p->tmp_buf);
10595                         }
10596  
10597                         /**
10598 -                        * 
10599 +                        *
10600                          * memcached is do expiration for us, as long as we can fetch it every thing is ok
10601 -                        * and the timestamp is updated 
10602 -                        * 
10603 +                        * and the timestamp is updated
10604 +                        *
10605                          */
10606 -                       if (NULL == (r = mc_aget(p->conf.mc, 
10607 +                       if (NULL == (r = mc_aget(p->conf.mc,
10608                                                  CONST_BUF_LEN(p->tmp_buf)
10609                                                  ))) {
10610 -                               
10611 +
10612                                 response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->conf.deny_url));
10613 -                               
10614 +
10615                                 con->http_status = 307;
10616 -                               
10617 +
10618                                 return HANDLER_FINISHED;
10619                         }
10620 -                       
10621 +
10622                         free(r);
10623 -                       
10624 +
10625                         /* set a new timeout */
10626 -                       if (0 != mc_set(p->conf.mc, 
10627 +                       if (0 != mc_set(p->conf.mc,
10628                                         CONST_BUF_LEN(p->tmp_buf),
10629                                         (char *)&(srv->cur_ts), sizeof(srv->cur_ts),
10630                                         p->conf.trigger_timeout, 0)) {
10631 @@ -507,13 +504,13 @@
10632                 }
10633  # endif
10634         }
10635 -       
10636 +
10637  #else
10638         UNUSED(srv);
10639         UNUSED(con);
10640         UNUSED(p_d);
10641  #endif
10642 -       
10643 +
10644         return HANDLER_GO_ON;
10645  }
10646  
10647 @@ -521,21 +518,21 @@
10648  TRIGGER_FUNC(mod_trigger_b4_dl_handle_trigger) {
10649         plugin_data *p = p_d;
10650         size_t i;
10651 -       
10652 +
10653         /* check DB each minute */
10654         if (srv->cur_ts % 60 != 0) return HANDLER_GO_ON;
10655 -       
10656 +
10657         /* cleanup */
10658         for (i = 0; i < srv->config_context->used; i++) {
10659                 plugin_config *s = p->config_storage[i];
10660                 datum key, val, okey;
10661 -               
10662 +
10663                 if (!s->db) continue;
10664 -               
10665 +
10666                 okey.dptr = NULL;
10667 -               
10668 -               /* according to the manual this loop + delete does delete all entries on its way 
10669 -                * 
10670 +
10671 +               /* according to the manual this loop + delete does delete all entries on its way
10672 +                *
10673                  * we don't care as the next round will remove them. We don't have to perfect here.
10674                  */
10675                 for (key = gdbm_firstkey(s->db); key.dptr; key = gdbm_nextkey(s->db, okey)) {
10676 @@ -544,21 +541,21 @@
10677                                 free(okey.dptr);
10678                                 okey.dptr = NULL;
10679                         }
10680 -                       
10681 +
10682                         val = gdbm_fetch(s->db, key);
10683 -                       
10684 +
10685                         last_hit = *(time_t *)(val.dptr);
10686 -                       
10687 +
10688                         free(val.dptr);
10689 -                       
10690 +
10691                         if (srv->cur_ts - last_hit > s->trigger_timeout) {
10692                                 gdbm_delete(s->db, key);
10693                         }
10694 -                       
10695 +
10696                         okey = key;
10697                 }
10698                 if (okey.dptr) free(okey.dptr);
10699 -               
10700 +
10701                 /* reorg once a day */
10702                 if ((srv->cur_ts % (60 * 60 * 24) != 0)) gdbm_reorganize(s->db);
10703         }
10704 @@ -571,7 +568,7 @@
10705  int mod_trigger_b4_dl_plugin_init(plugin *p) {
10706         p->version     = LIGHTTPD_VERSION_ID;
10707         p->name        = buffer_init_string("trigger_b4_dl");
10708 -       
10709 +
10710         p->init        = mod_trigger_b4_dl_init;
10711         p->handle_uri_clean  = mod_trigger_b4_dl_uri_handler;
10712         p->set_defaults  = mod_trigger_b4_dl_set_defaults;
10713 @@ -579,8 +576,8 @@
10714         p->handle_trigger  = mod_trigger_b4_dl_handle_trigger;
10715  #endif
10716         p->cleanup     = mod_trigger_b4_dl_free;
10717 -       
10718 +
10719         p->data        = NULL;
10720 -       
10721 +
10722         return 0;
10723  }
10724
10725 Property changes on: src/mod_trigger_b4_dl.c
10726 ___________________________________________________________________
10727 Name: svn:eol-style
10728    + native
10729
10730 Index: src/mod_evhost.c
10731 ===================================================================
10732 --- src/mod_evhost.c    (.../tags/lighttpd-1.4.11)      (revision 1159)
10733 +++ src/mod_evhost.c    (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
10734 @@ -7,10 +7,12 @@
10735  #include "response.h"
10736  #include "stat_cache.h"
10737  
10738 +#include "sys-files.h"
10739 +
10740  typedef struct {
10741         /* unparsed pieces */
10742         buffer *path_pieces_raw;
10743 -       
10744 +
10745         /* pieces for path creation */
10746         size_t len;
10747         buffer **path_pieces;
10748 @@ -21,14 +23,14 @@
10749         buffer *tmp_buf;
10750  
10751         plugin_config **config_storage;
10752 -       plugin_config conf; 
10753 +       plugin_config conf;
10754  } plugin_data;
10755  
10756  INIT_FUNC(mod_evhost_init) {
10757         plugin_data *p;
10758 -       
10759 +
10760         p = calloc(1, sizeof(*p));
10761 -       
10762 +
10763         p->tmp_buf = buffer_init();
10764  
10765         return p;
10766 @@ -36,34 +38,34 @@
10767  
10768  FREE_FUNC(mod_evhost_free) {
10769         plugin_data *p = p_d;
10770 -       
10771 +
10772         UNUSED(srv);
10773  
10774         if (!p) return HANDLER_GO_ON;
10775 -       
10776 +
10777         if (p->config_storage) {
10778                 size_t i;
10779                 for (i = 0; i < srv->config_context->used; i++) {
10780                         plugin_config *s = p->config_storage[i];
10781  
10782                         if (!s) continue;
10783 -                       
10784 +
10785                         if(s->path_pieces) {
10786                                 size_t j;
10787                                 for (j = 0; j < s->len; j++) {
10788                                         buffer_free(s->path_pieces[j]);
10789                                 }
10790 -                               
10791 +
10792                                 free(s->path_pieces);
10793                         }
10794 -                       
10795 +
10796                         buffer_free(s->path_pieces_raw);
10797 -                       
10798 +
10799                         free(s);
10800                 }
10801                 free(p->config_storage);
10802         }
10803 -       
10804 +
10805         buffer_free(p->tmp_buf);
10806  
10807         free(p);
10808 @@ -73,30 +75,30 @@
10809  
10810  static void mod_evhost_parse_pattern(plugin_config *s) {
10811         char *ptr = s->path_pieces_raw->ptr,*pos;
10812 -       
10813 +
10814         s->path_pieces = NULL;
10815 -       
10816 +
10817         for(pos=ptr;*ptr;ptr++) {
10818                 if(*ptr == '%') {
10819                         s->path_pieces = realloc(s->path_pieces,(s->len+2) * sizeof(*s->path_pieces));
10820                         s->path_pieces[s->len] = buffer_init();
10821                         s->path_pieces[s->len+1] = buffer_init();
10822 -                       
10823 +
10824                         buffer_copy_string_len(s->path_pieces[s->len],pos,ptr-pos);
10825                         pos = ptr + 2;
10826 -                       
10827 +
10828                         buffer_copy_string_len(s->path_pieces[s->len+1],ptr++,2);
10829 -                       
10830 +
10831                         s->len += 2;
10832                 }
10833         }
10834 -       
10835 +
10836         if(*pos != '\0') {
10837                 s->path_pieces = realloc(s->path_pieces,(s->len+1) * sizeof(*s->path_pieces));
10838                 s->path_pieces[s->len] = buffer_init();
10839 -               
10840 +
10841                 buffer_append_memory(s->path_pieces[s->len],pos,ptr-pos);
10842 -               
10843 +
10844                 s->len += 1;
10845         }
10846  }
10847 @@ -104,9 +106,9 @@
10848  SETDEFAULTS_FUNC(mod_evhost_set_defaults) {
10849         plugin_data *p = p_d;
10850         size_t i;
10851 -       
10852 +
10853         /**
10854 -        * 
10855 +        *
10856          * #
10857          * # define a pattern for the host url finding
10858          * # %% => % sign
10859 @@ -117,39 +119,39 @@
10860          * # %4 => subdomain 2 name
10861          * #
10862          * evhost.path-pattern = "/home/ckruse/dev/www/%3/htdocs/"
10863 -        * 
10864 +        *
10865          */
10866 -       
10867 -       config_values_t cv[] = { 
10868 +
10869 +       config_values_t cv[] = {
10870                 { "evhost.path-pattern",            NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
10871                 { NULL,                             NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
10872         };
10873 -       
10874 +
10875         if (!p) return HANDLER_ERROR;
10876 -       
10877 +
10878         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
10879 -       
10880 +
10881         for (i = 0; i < srv->config_context->used; i++) {
10882                 plugin_config *s;
10883 -               
10884 +
10885                 s = calloc(1, sizeof(plugin_config));
10886                 s->path_pieces_raw = buffer_init();
10887                 s->path_pieces     = NULL;
10888                 s->len             = 0;
10889 -       
10890 +
10891                 cv[0].destination = s->path_pieces_raw;
10892 -               
10893 +
10894                 p->config_storage[i] = s;
10895 -               
10896 +
10897                 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value,  cv)) {
10898                         return HANDLER_ERROR;
10899                 }
10900 -               
10901 +
10902                 if (s->path_pieces_raw->used != 0) {
10903                         mod_evhost_parse_pattern(s);
10904                 }
10905         }
10906 -       
10907 +
10908         return HANDLER_GO_ON;
10909  }
10910  
10911 @@ -158,7 +160,7 @@
10912   * - %0 - full hostname (authority w/o port)
10913   * - %1 - tld
10914   * - %2 - domain.tld
10915 - * - %3 - 
10916 + * - %3 -
10917   */
10918  
10919  static int mod_evhost_parse_host(connection *con,array *host) {
10920 @@ -168,7 +170,7 @@
10921         int first = 1;
10922         data_string *ds;
10923         int i;
10924 -       
10925 +
10926         /* first, find the domain + tld */
10927         for(;ptr > con->uri.authority->ptr;ptr--) {
10928                 if(*ptr == '.') {
10929 @@ -179,18 +181,18 @@
10930                         first = 1;
10931                 }
10932         }
10933 -       
10934 +
10935         ds = data_string_init();
10936         buffer_copy_string(ds->key,"%0");
10937 -       
10938 +
10939         /* if we stopped at a dot, skip the dot */
10940         if (*ptr == '.') ptr++;
10941         buffer_copy_string_len(ds->value, ptr, colon-ptr);
10942 -       
10943 +
10944         array_insert_unique(host,(data_unset *)ds);
10945 -       
10946 +
10947         /* if the : is not the start of the authority, go on parsing the hostname */
10948 -       
10949 +
10950         if (colon != con->uri.authority->ptr) {
10951                 for(ptr = colon - 1, i = 1; ptr > con->uri.authority->ptr; ptr--) {
10952                         if(*ptr == '.') {
10953 @@ -200,60 +202,56 @@
10954                                         buffer_copy_string(ds->key,"%");
10955                                         buffer_append_long(ds->key, i++);
10956                                         buffer_copy_string_len(ds->value,ptr+1,colon-ptr-1);
10957 -                                       
10958 +
10959                                         array_insert_unique(host,(data_unset *)ds);
10960                                 }
10961                                 colon = ptr;
10962                         }
10963                 }
10964 -               
10965 +
10966                 /* if the . is not the first charactor of the hostname */
10967                 if (colon != ptr) {
10968                         ds = data_string_init();
10969                         buffer_copy_string(ds->key,"%");
10970                         buffer_append_long(ds->key, i++);
10971                         buffer_copy_string_len(ds->value,ptr,colon-ptr);
10972 -                       
10973 +
10974                         array_insert_unique(host,(data_unset *)ds);
10975                 }
10976         }
10977 -       
10978 +
10979         return 0;
10980  }
10981  
10982 -#define PATCH(x) \
10983 -       p->conf.x = s->x;
10984  static int mod_evhost_patch_connection(server *srv, connection *con, plugin_data *p) {
10985         size_t i, j;
10986         plugin_config *s = p->config_storage[0];
10987 -       
10988 -       PATCH(path_pieces);
10989 -       PATCH(len);
10990 -       
10991 +
10992 +       PATCH_OPTION(path_pieces);
10993 +       PATCH_OPTION(len);
10994 +
10995         /* skip the first, the global context */
10996         for (i = 1; i < srv->config_context->used; i++) {
10997                 data_config *dc = (data_config *)srv->config_context->data[i];
10998                 s = p->config_storage[i];
10999 -               
11000 +
11001                 /* condition didn't match */
11002                 if (!config_check_cond(srv, con, dc)) continue;
11003 -               
11004 +
11005                 /* merge config */
11006                 for (j = 0; j < dc->value->used; j++) {
11007                         data_unset *du = dc->value->data[j];
11008 -                       
11009 +
11010                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("evhost.path-pattern"))) {
11011 -                               PATCH(path_pieces);
11012 -                               PATCH(len);
11013 +                               PATCH_OPTION(path_pieces);
11014 +                               PATCH_OPTION(len);
11015                         }
11016                 }
11017         }
11018 -       
11019 +
11020         return 0;
11021  }
11022 -#undef PATCH
11023  
11024 -
11025  static handler_t mod_evhost_uri_handler(server *srv, connection *con, void *p_d) {
11026         plugin_data *p = p_d;
11027         size_t i;
11028 @@ -261,29 +259,29 @@
11029         register char *ptr;
11030         int not_good = 0;
11031         stat_cache_entry *sce = NULL;
11032 -       
11033 +
11034         /* not authority set */
11035         if (con->uri.authority->used == 0) return HANDLER_GO_ON;
11036 -       
11037 +
11038         mod_evhost_patch_connection(srv, con, p);
11039 -       
11040 +
11041         /* missing even default(global) conf */
11042         if (0 == p->conf.len) {
11043                 return HANDLER_GO_ON;
11044         }
11045  
11046         parsed_host = array_init();
11047 -       
11048 +
11049         mod_evhost_parse_host(con, parsed_host);
11050 -       
11051 +
11052         /* build document-root */
11053         buffer_reset(p->tmp_buf);
11054 -       
11055 +
11056         for (i = 0; i < p->conf.len; i++) {
11057                 ptr = p->conf.path_pieces[i]->ptr;
11058                 if (*ptr == '%') {
11059                         data_string *ds;
11060 -                       
11061 +
11062                         if (*(ptr+1) == '%') {
11063                                 /* %% */
11064                                 BUFFER_APPEND_STRING_CONST(p->tmp_buf,"%");
11065 @@ -298,11 +296,11 @@
11066                         buffer_append_string_buffer(p->tmp_buf,p->conf.path_pieces[i]);
11067                 }
11068         }
11069 -       
11070 -       BUFFER_APPEND_SLASH(p->tmp_buf);
11071 -       
11072 +
11073 +       PATHNAME_APPEND_SLASH(p->tmp_buf);
11074 +
11075         array_free(parsed_host);
11076 -       
11077 +
11078         if (HANDLER_ERROR == stat_cache_get_entry(srv, con, p->tmp_buf, &sce)) {
11079                 log_error_write(srv, __FILE__, __LINE__, "sb", strerror(errno), p->tmp_buf);
11080                 not_good = 1;
11081 @@ -310,11 +308,11 @@
11082                 log_error_write(srv, __FILE__, __LINE__, "sb", "not a directory:", p->tmp_buf);
11083                 not_good = 1;
11084         }
11085 -       
11086 +
11087         if (!not_good) {
11088                 buffer_copy_string_buffer(con->physical.doc_root, p->tmp_buf);
11089         }
11090 -       
11091 +
11092         return HANDLER_GO_ON;
11093  }
11094  
11095 @@ -325,9 +323,9 @@
11096         p->set_defaults            = mod_evhost_set_defaults;
11097         p->handle_docroot          = mod_evhost_uri_handler;
11098         p->cleanup                 = mod_evhost_free;
11099 -       
11100 +
11101         p->data                    = NULL;
11102 -       
11103 +
11104         return 0;
11105  }
11106  
11107
11108 Property changes on: src/mod_evhost.c
11109 ___________________________________________________________________
11110 Name: svn:eol-style
11111    + native
11112
11113 Index: src/splaytree.c
11114 ===================================================================
11115 --- src/splaytree.c     (.../tags/lighttpd-1.4.11)      (revision 1159)
11116 +++ src/splaytree.c     (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
11117 @@ -56,19 +56,19 @@
11118  
11119  #define node_size splaytree_size
11120  
11121 -/* Splay using the key i (which may or may not be in the tree.) 
11122 - * The starting root is t, and the tree used is defined by rat 
11123 +/* Splay using the key i (which may or may not be in the tree.)
11124 + * The starting root is t, and the tree used is defined by rat
11125   * size fields are maintained */
11126  splay_tree * splaytree_splay (splay_tree *t, int i) {
11127      splay_tree N, *l, *r, *y;
11128      int comp, root_size, l_size, r_size;
11129 -    
11130 +
11131      if (t == NULL) return t;
11132      N.left = N.right = NULL;
11133      l = r = &N;
11134      root_size = node_size(t);
11135      l_size = r_size = 0;
11136
11137 +
11138      for (;;) {
11139          comp = compare(i, t->key);
11140          if (comp < 0) {
11141 @@ -120,7 +120,7 @@
11142          y->size = r_size;
11143          r_size -= 1+node_size(y->right);
11144      }
11145
11146 +
11147      l->right = t->left;                                /* assemble */
11148      r->left = t->right;
11149      t->left = N.right;
11150
11151 Property changes on: src/splaytree.c
11152 ___________________________________________________________________
11153 Name: svn:eol-style
11154    + native
11155
11156 Index: src/chunk.c
11157 ===================================================================
11158 --- src/chunk.c (.../tags/lighttpd-1.4.11)      (revision 1159)
11159 +++ src/chunk.c (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
11160 @@ -1,16 +1,14 @@
11161  /**
11162   * the network chunk-API
11163 - * 
11164 - * 
11165 + *
11166 + *
11167   */
11168  
11169  #include <sys/types.h>
11170  #include <sys/stat.h>
11171 -#include <sys/mman.h>
11172  
11173  #include <stdlib.h>
11174  #include <fcntl.h>
11175 -#include <unistd.h>
11176  
11177  #include <stdio.h>
11178  #include <errno.h>
11179 @@ -18,36 +16,39 @@
11180  
11181  #include "chunk.h"
11182  
11183 +#include "sys-mmap.h"
11184 +#include "sys-files.h"
11185 +
11186  chunkqueue *chunkqueue_init(void) {
11187         chunkqueue *cq;
11188 -       
11189 +
11190         cq = calloc(1, sizeof(*cq));
11191 -       
11192 +
11193         cq->first = NULL;
11194         cq->last = NULL;
11195 -       
11196 +
11197         cq->unused = NULL;
11198 -       
11199 +
11200         return cq;
11201  }
11202  
11203  static chunk *chunk_init(void) {
11204         chunk *c;
11205 -       
11206 +
11207         c = calloc(1, sizeof(*c));
11208 -       
11209 +
11210         c->mem = buffer_init();
11211         c->file.name = buffer_init();
11212         c->file.fd = -1;
11213         c->file.mmap.start = MAP_FAILED;
11214         c->next = NULL;
11215 -       
11216 +
11217         return c;
11218  }
11219  
11220  static void chunk_free(chunk *c) {
11221         if (!c) return;
11222 -       
11223 +
11224         buffer_free(c->mem);
11225         buffer_free(c->file.name);
11226  
11227 @@ -56,13 +57,13 @@
11228  
11229  static void chunk_reset(chunk *c) {
11230         if (!c) return;
11231 -       
11232 +
11233         buffer_reset(c->mem);
11234  
11235         if (c->file.is_temp && !buffer_is_empty(c->file.name)) {
11236                 unlink(c->file.name->ptr);
11237         }
11238 -       
11239 +
11240         buffer_reset(c->file.name);
11241  
11242         if (c->file.fd != -1) {
11243 @@ -78,28 +79,28 @@
11244  
11245  void chunkqueue_free(chunkqueue *cq) {
11246         chunk *c, *pc;
11247 -       
11248 +
11249         if (!cq) return;
11250 -       
11251 +
11252         for (c = cq->first; c; ) {
11253                 pc = c;
11254                 c = c->next;
11255                 chunk_free(pc);
11256         }
11257 -       
11258 +
11259         for (c = cq->unused; c; ) {
11260                 pc = c;
11261                 c = c->next;
11262                 chunk_free(pc);
11263         }
11264 -       
11265 +
11266         free(cq);
11267  }
11268  
11269  static chunk *chunkqueue_get_unused_chunk(chunkqueue *cq) {
11270         chunk *c;
11271 -       
11272 -       /* check if we have a unused chunk */
11273 +
11274 +       /* check if we have an unused chunk */
11275         if (!cq->unused) {
11276                 c = chunk_init();
11277         } else {
11278 @@ -109,18 +110,18 @@
11279                 c->next = NULL;
11280                 cq->unused_chunks--;
11281         }
11282 -       
11283 +
11284         return c;
11285  }
11286  
11287  static int chunkqueue_prepend_chunk(chunkqueue *cq, chunk *c) {
11288         c->next = cq->first;
11289         cq->first = c;
11290 -       
11291 +
11292         if (cq->last == NULL) {
11293                 cq->last = c;
11294         }
11295 -       
11296 +
11297         return 0;
11298  }
11299  
11300 @@ -129,19 +130,19 @@
11301                 cq->last->next = c;
11302         }
11303         cq->last = c;
11304 -       
11305 +
11306         if (cq->first == NULL) {
11307                 cq->first = c;
11308         }
11309 -       
11310 +
11311         return 0;
11312  }
11313  
11314  void chunkqueue_reset(chunkqueue *cq) {
11315         chunk *c;
11316         /* move everything to the unused queue */
11317 -       
11318 -       /* mark all read written */ 
11319 +
11320 +       /* mark all read written */
11321         for (c = cq->first; c; c = c->next) {
11322                 switch(c->type) {
11323                 case MEM_CHUNK:
11324 @@ -150,7 +151,7 @@
11325                 case FILE_CHUNK:
11326                         c->offset = c->file.length;
11327                         break;
11328 -               default: 
11329 +               default:
11330                         break;
11331                 }
11332         }
11333 @@ -162,93 +163,93 @@
11334  
11335  int chunkqueue_append_file(chunkqueue *cq, buffer *fn, off_t offset, off_t len) {
11336         chunk *c;
11337 -       
11338 +
11339         if (len == 0) return 0;
11340 -       
11341 +
11342         c = chunkqueue_get_unused_chunk(cq);
11343 -       
11344 +
11345         c->type = FILE_CHUNK;
11346 -       
11347 +
11348         buffer_copy_string_buffer(c->file.name, fn);
11349         c->file.start = offset;
11350         c->file.length = len;
11351         c->offset = 0;
11352 -       
11353 +
11354         chunkqueue_append_chunk(cq, c);
11355 -       
11356 +
11357         return 0;
11358  }
11359  
11360  int chunkqueue_append_buffer(chunkqueue *cq, buffer *mem) {
11361         chunk *c;
11362 -       
11363 +
11364         if (mem->used == 0) return 0;
11365 -       
11366 +
11367         c = chunkqueue_get_unused_chunk(cq);
11368         c->type = MEM_CHUNK;
11369         c->offset = 0;
11370         buffer_copy_string_buffer(c->mem, mem);
11371 -       
11372 +
11373         chunkqueue_append_chunk(cq, c);
11374 -       
11375 +
11376         return 0;
11377  }
11378  
11379  int chunkqueue_prepend_buffer(chunkqueue *cq, buffer *mem) {
11380         chunk *c;
11381 -       
11382 +
11383         if (mem->used == 0) return 0;
11384 -       
11385 +
11386         c = chunkqueue_get_unused_chunk(cq);
11387         c->type = MEM_CHUNK;
11388         c->offset = 0;
11389         buffer_copy_string_buffer(c->mem, mem);
11390 -       
11391 +
11392         chunkqueue_prepend_chunk(cq, c);
11393 -       
11394 +
11395         return 0;
11396  }
11397  
11398  int chunkqueue_append_mem(chunkqueue *cq, const char * mem, size_t len) {
11399         chunk *c;
11400 -       
11401 +
11402         if (len == 0) return 0;
11403 -       
11404 +
11405         c = chunkqueue_get_unused_chunk(cq);
11406         c->type = MEM_CHUNK;
11407         c->offset = 0;
11408         buffer_copy_string_len(c->mem, mem, len - 1);
11409 -       
11410 +
11411         chunkqueue_append_chunk(cq, c);
11412 -       
11413 +
11414         return 0;
11415  }
11416  
11417  buffer * chunkqueue_get_prepend_buffer(chunkqueue *cq) {
11418         chunk *c;
11419 -       
11420 +
11421         c = chunkqueue_get_unused_chunk(cq);
11422 -       
11423 +
11424         c->type = MEM_CHUNK;
11425         c->offset = 0;
11426         buffer_reset(c->mem);
11427 -       
11428 +
11429         chunkqueue_prepend_chunk(cq, c);
11430 -       
11431 +
11432         return c->mem;
11433  }
11434  
11435  buffer *chunkqueue_get_append_buffer(chunkqueue *cq) {
11436         chunk *c;
11437 -       
11438 +
11439         c = chunkqueue_get_unused_chunk(cq);
11440 -       
11441 +
11442         c->type = MEM_CHUNK;
11443         c->offset = 0;
11444         buffer_reset(c->mem);
11445 -       
11446 +
11447         chunkqueue_append_chunk(cq, c);
11448 -       
11449 +
11450         return c->mem;
11451  }
11452  
11453 @@ -263,7 +264,7 @@
11454  chunk *chunkqueue_get_append_tempfile(chunkqueue *cq) {
11455         chunk *c;
11456         buffer *template = buffer_init_string("/var/tmp/lighttpd-upload-XXXXXX");
11457 -       
11458 +
11459         c = chunkqueue_get_unused_chunk(cq);
11460  
11461         c->type = FILE_CHUNK;
11462 @@ -273,12 +274,12 @@
11463                 size_t i;
11464  
11465                 /* we have several tempdirs, only if all of them fail we jump out */
11466 -               
11467 +
11468                 for (i = 0; i < cq->tempdirs->used; i++) {
11469                         data_string *ds = (data_string *)cq->tempdirs->data[i];
11470  
11471                         buffer_copy_string_buffer(template, ds->value);
11472 -                       BUFFER_APPEND_SLASH(template);
11473 +                       PATHNAME_APPEND_SLASH(template);
11474                         BUFFER_APPEND_STRING_CONST(template, "lighttpd-upload-XXXXXX");
11475  
11476                         if (-1 != (c->file.fd = mkstemp(template->ptr))) {
11477 @@ -300,7 +301,7 @@
11478         chunkqueue_append_chunk(cq, c);
11479  
11480         buffer_free(template);
11481 -       
11482 +
11483         return c;
11484  }
11485  
11486 @@ -308,7 +309,7 @@
11487  off_t chunkqueue_length(chunkqueue *cq) {
11488         off_t len = 0;
11489         chunk *c;
11490 -       
11491 +
11492         for (c = cq->first; c; c = c->next) {
11493                 switch (c->type) {
11494                 case MEM_CHUNK:
11495 @@ -321,14 +322,14 @@
11496                         break;
11497                 }
11498         }
11499 -       
11500 +
11501         return len;
11502  }
11503  
11504  off_t chunkqueue_written(chunkqueue *cq) {
11505         off_t len = 0;
11506         chunk *c;
11507 -       
11508 +
11509         for (c = cq->first; c; c = c->next) {
11510                 switch (c->type) {
11511                 case MEM_CHUNK:
11512 @@ -339,7 +340,7 @@
11513                         break;
11514                 }
11515         }
11516 -       
11517 +
11518         return len;
11519  }
11520  
11521 @@ -358,9 +359,9 @@
11522                         if (c->offset == (off_t)c->mem->used - 1) is_finished = 1;
11523                         break;
11524                 case FILE_CHUNK:
11525 -                       if (c->offset == c->file.length) is_finished = 1; 
11526 +                       if (c->offset == c->file.length) is_finished = 1;
11527                         break;
11528 -               default: 
11529 +               default:
11530                         break;
11531                 }
11532  
11533
11534 Property changes on: src/chunk.c
11535 ___________________________________________________________________
11536 Name: svn:eol-style
11537    + native
11538
11539 Index: src/configfile.h
11540 ===================================================================
11541 --- src/configfile.h    (.../tags/lighttpd-1.4.11)      (revision 1159)
11542 +++ src/configfile.h    (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
11543 @@ -9,7 +9,7 @@
11544         server *srv;
11545         int     ok;
11546         array  *all_configs;
11547 -       array  *configs_stack; /* to parse nested block */
11548 +       buffer_ptr  *configs_stack; /* to parse nested block */
11549         data_config *current; /* current started with { */
11550         buffer *basedir;
11551  } config_t;
11552
11553 Property changes on: src/configfile.h
11554 ___________________________________________________________________
11555 Name: svn:eol-style
11556    + native
11557
11558 Index: src/lemon.c
11559 ===================================================================
11560 --- src/lemon.c (.../tags/lighttpd-1.4.11)      (revision 1159)
11561 +++ src/lemon.c (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
11562 @@ -579,7 +579,7 @@
11563  */
11564  
11565  /* Find a precedence symbol of every rule in the grammar.
11566 -** 
11567 +**
11568  ** Those rules which have a precedence symbol coded in the input
11569  ** grammar using the "[symbol]" construct will already have the
11570  ** rp->precsym field filled.  Other rules take as their precedence
11571 @@ -869,7 +869,7 @@
11572        cfp->status = INCOMPLETE;
11573      }
11574    }
11575 -  
11576 +
11577    do{
11578      progress = 0;
11579      for(i=0; i<lemp->nstate; i++){
11580 @@ -900,7 +900,7 @@
11581    struct symbol *sp;
11582    struct rule *rp;
11583  
11584 -  /* Add all of the reduce actions 
11585 +  /* Add all of the reduce actions
11586    ** A reduce action is added for each element of the followset of
11587    ** a configuration which has its dot at the extreme right.
11588    */
11589 @@ -1017,7 +1017,7 @@
11590        apx->type = RD_RESOLVED;
11591      }
11592    }else{
11593 -    assert( 
11594 +    assert(
11595        apx->type==SH_RESOLVED ||
11596        apx->type==RD_RESOLVED ||
11597        apx->type==CONFLICT ||
11598 @@ -1350,7 +1350,7 @@
11599    OptInit(argv,options,stderr);
11600    if( version ){
11601       printf("Lemon version 1.0\n");
11602 -     exit(0); 
11603 +     exit(0);
11604    }
11605    if( OptNArgs() < 1 ){
11606      fprintf(stderr,"Exactly one filename argument is required.\n");
11607 @@ -2031,7 +2031,7 @@
11608      case IN_RHS:
11609        if( x[0]=='.' ){
11610          struct rule *rp;
11611 -        rp = (struct rule *)malloc( sizeof(struct rule) + 
11612 +        rp = (struct rule *)malloc( sizeof(struct rule) +
11613               sizeof(struct symbol*)*psp->nrhs + sizeof(char*)*psp->nrhs );
11614          if( rp==0 ){
11615            ErrorMsg(psp->filename,psp->tokenlineno,
11616 @@ -2546,7 +2546,7 @@
11617    return fp;
11618  }
11619  
11620 -/* Duplicate the input file without comments and without actions 
11621 +/* Duplicate the input file without comments and without actions
11622  ** on rules */
11623  void Reprint(lemp)
11624  struct lemon *lemp;
11625 @@ -2822,7 +2822,7 @@
11626  PRIVATE FILE *tplt_open(lemp)
11627  struct lemon *lemp;
11628  {
11629 -  
11630 +
11631    char buf[1000];
11632    FILE *in;
11633    char *tpltname;
11634 @@ -2930,7 +2930,7 @@
11635    return ret;
11636  }
11637  
11638 -/* 
11639 +/*
11640  ** Generate code which executes when the rule "rp" is reduced.  Write
11641  ** the code to "out".  Make sure lineno stays up-to-date.
11642  */
11643 @@ -3384,7 +3384,7 @@
11644  
11645    /* Output the yy_shift_ofst[] table */
11646    fprintf(out, "#define YY_SHIFT_USE_DFLT (%d)\n", mnTknOfst-1); lineno++;
11647 -  fprintf(out, "static %s yy_shift_ofst[] = {\n", 
11648 +  fprintf(out, "static %s yy_shift_ofst[] = {\n",
11649            minimum_size_type(mnTknOfst-1, mxTknOfst)); lineno++;
11650    n = lemp->nstate;
11651    for(i=j=0; i<n; i++){
11652 @@ -3405,7 +3405,7 @@
11653  
11654    /* Output the yy_reduce_ofst[] table */
11655    fprintf(out, "#define YY_REDUCE_USE_DFLT (%d)\n", mnNtOfst-1); lineno++;
11656 -  fprintf(out, "static %s yy_reduce_ofst[] = {\n", 
11657 +  fprintf(out, "static %s yy_reduce_ofst[] = {\n",
11658            minimum_size_type(mnNtOfst-1, mxNtOfst)); lineno++;
11659    n = lemp->nstate;
11660    for(i=j=0; i<n; i++){
11661 @@ -3480,7 +3480,7 @@
11662    tplt_xfer(lemp->name,in,out,&lineno);
11663  
11664    /* Generate code which executes every time a symbol is popped from
11665 -  ** the stack while processing errors or while destroying the parser. 
11666 +  ** the stack while processing errors or while destroying the parser.
11667    ** (In other words, generate the %destructor actions)
11668    */
11669    if( lemp->tokendest ){
11670 @@ -3522,7 +3522,7 @@
11671    tplt_print(out,lemp,lemp->overflow,lemp->overflowln,&lineno);
11672    tplt_xfer(lemp->name,in,out,&lineno);
11673  
11674 -  /* Generate the table of rule information 
11675 +  /* Generate the table of rule information
11676    **
11677    ** Note: This code depends on the fact that rules are number
11678    ** sequentually beginning with 0.
11679 @@ -3589,7 +3589,7 @@
11680      for(i=1; i<lemp->nterminal; i++){
11681        fprintf(out,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i);
11682      }
11683 -    fclose(out);  
11684 +    fclose(out);
11685    }
11686    return;
11687  }
11688 @@ -3630,7 +3630,7 @@
11689          rbest = rp;
11690        }
11691      }
11692
11693 +
11694      /* Do not make a default if the number of rules to default
11695      ** is not at least 2 */
11696      if( nbest<2 ) continue;
11697 @@ -3781,7 +3781,7 @@
11698    if( x1a ){
11699      x1a->size = 1024;
11700      x1a->count = 0;
11701 -    x1a->tbl = (x1node*)malloc( 
11702 +    x1a->tbl = (x1node*)malloc(
11703        (sizeof(x1node) + sizeof(x1node*))*1024 );
11704      if( x1a->tbl==0 ){
11705        free(x1a);
11706 @@ -3943,7 +3943,7 @@
11707    if( x2a ){
11708      x2a->size = 128;
11709      x2a->count = 0;
11710 -    x2a->tbl = (x2node*)malloc( 
11711 +    x2a->tbl = (x2node*)malloc(
11712        (sizeof(x2node) + sizeof(x2node*))*128 );
11713      if( x2a->tbl==0 ){
11714        free(x2a);
11715 @@ -4149,7 +4149,7 @@
11716    if( x3a ){
11717      x3a->size = 128;
11718      x3a->count = 0;
11719 -    x3a->tbl = (x3node*)malloc( 
11720 +    x3a->tbl = (x3node*)malloc(
11721        (sizeof(x3node) + sizeof(x3node*))*128 );
11722      if( x3a->tbl==0 ){
11723        free(x3a);
11724 @@ -4295,7 +4295,7 @@
11725    if( x4a ){
11726      x4a->size = 64;
11727      x4a->count = 0;
11728 -    x4a->tbl = (x4node*)malloc( 
11729 +    x4a->tbl = (x4node*)malloc(
11730        (sizeof(x4node) + sizeof(x4node*))*64 );
11731      if( x4a->tbl==0 ){
11732        free(x4a);
11733
11734 Property changes on: src/lemon.c
11735 ___________________________________________________________________
11736 Name: svn:eol-style
11737    + native
11738
11739 Index: src/sys-strings.h
11740 ===================================================================
11741 --- src/sys-strings.h   (.../tags/lighttpd-1.4.11)      (revision 0)
11742 +++ src/sys-strings.h   (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
11743 @@ -0,0 +1,11 @@
11744 +#ifndef _SYS_STRINGS_H_
11745 +#define _SYS_STRINGS_H_
11746 +
11747 +#ifdef _WIN32
11748 +#define strcasecmp stricmp
11749 +#define strncasecmp strnicmp
11750 +#define strtoll(p, e, b) _strtoi64(p, e, b)
11751 +#endif
11752 +
11753 +#endif
11754 +
11755
11756 Property changes on: src/sys-strings.h
11757 ___________________________________________________________________
11758 Name: svn:eol-style
11759    + native
11760
11761 Index: src/fdevent_solaris_devpoll.c
11762 ===================================================================
11763 --- src/fdevent_solaris_devpoll.c       (.../tags/lighttpd-1.4.11)      (revision 1159)
11764 +++ src/fdevent_solaris_devpoll.c       (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
11765 @@ -1,6 +1,5 @@
11766  #include <sys/types.h>
11767  
11768 -#include <unistd.h>
11769  #include <stdlib.h>
11770  #include <stdio.h>
11771  #include <string.h>
11772 @@ -23,55 +22,55 @@
11773  
11774  static int fdevent_solaris_devpoll_event_del(fdevents *ev, int fde_ndx, int fd) {
11775         struct pollfd pfd;
11776 -               
11777 +
11778         if (fde_ndx < 0) return -1;
11779 -       
11780 +
11781         pfd.fd = fd;
11782         pfd.events = POLLREMOVE;
11783         pfd.revents = 0;
11784 -       
11785 +
11786         if (-1 == write(ev->devpoll_fd, &pfd, sizeof(pfd))) {
11787 -               fprintf(stderr, "%s.%d: (del) write failed: (%d, %s)\n", 
11788 -                       __FILE__, __LINE__, 
11789 +               fprintf(stderr, "%s.%d: (del) write failed: (%d, %s)\n",
11790 +                       __FILE__, __LINE__,
11791                         fd, strerror(errno));
11792 -               
11793 +
11794                 return -1;
11795         }
11796 -       
11797 +
11798         return -1;
11799  }
11800  
11801  static int fdevent_solaris_devpoll_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
11802         struct pollfd pfd;
11803         int add = 0;
11804 -               
11805 +
11806         if (fde_ndx == -1) add = 1;
11807 -       
11808 +
11809         pfd.fd = fd;
11810         pfd.events = events;
11811         pfd.revents = 0;
11812 -       
11813 +
11814         if (-1 == write(ev->devpoll_fd, &pfd, sizeof(pfd))) {
11815 -               fprintf(stderr, "%s.%d: (del) write failed: (%d, %s)\n", 
11816 -                       __FILE__, __LINE__, 
11817 +               fprintf(stderr, "%s.%d: (del) write failed: (%d, %s)\n",
11818 +                       __FILE__, __LINE__,
11819                         fd, strerror(errno));
11820 -               
11821 +
11822                 return -1;
11823         }
11824 -       
11825 +
11826         return fd;
11827  }
11828  
11829  static int fdevent_solaris_devpoll_poll(fdevents *ev, int timeout_ms) {
11830         struct dvpoll dopoll;
11831         int ret;
11832 -       
11833 +
11834         dopoll.dp_timeout = timeout_ms;
11835         dopoll.dp_nfds = ev->maxfds;
11836         dopoll.dp_fds = ev->devpollfds;
11837 -       
11838 +
11839         ret = ioctl(ev->devpoll_fd, DP_POLL, &dopoll);
11840 -       
11841 +
11842         return ret;
11843  }
11844  
11845 @@ -85,11 +84,11 @@
11846  
11847  static int fdevent_solaris_devpoll_event_next_fdndx(fdevents *ev, int last_ndx) {
11848         size_t i;
11849 -       
11850 +
11851         UNUSED(ev);
11852  
11853         i = (last_ndx < 0) ? 0 : last_ndx + 1;
11854 -       
11855 +
11856         return i;
11857  }
11858  
11859 @@ -117,20 +116,20 @@
11860         ev->type = FDEVENT_HANDLER_SOLARIS_DEVPOLL;
11861  #define SET(x) \
11862         ev->x = fdevent_solaris_devpoll_##x;
11863 -       
11864 +
11865         SET(free);
11866         SET(poll);
11867         SET(reset);
11868 -       
11869 +
11870         SET(event_del);
11871         SET(event_add);
11872 -       
11873 +
11874         SET(event_next_fdndx);
11875         SET(event_get_fd);
11876         SET(event_get_revent);
11877 -       
11878 +
11879         ev->devpollfds = malloc(sizeof(*ev->devpollfds) * ev->maxfds);
11880 -       
11881 +
11882         if ((ev->devpoll_fd = open("/dev/poll", O_RDWR)) < 0) {
11883                 fprintf(stderr, "%s.%d: opening /dev/poll failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n",
11884                         __FILE__, __LINE__, strerror(errno));
11885 @@ -152,7 +151,7 @@
11886  
11887         fprintf(stderr, "%s.%d: solaris-devpoll not supported, try to set server.event-handler = \"poll\" or \"select\"\n",
11888                         __FILE__, __LINE__);
11889 -       
11890 +
11891         return -1;
11892  }
11893  #endif
11894
11895 Property changes on: src/fdevent_solaris_devpoll.c
11896 ___________________________________________________________________
11897 Name: svn:eol-style
11898    + native
11899
11900 Index: src/splaytree.h
11901 ===================================================================
11902 --- src/splaytree.h     (.../tags/lighttpd-1.4.11)      (revision 1159)
11903 +++ src/splaytree.h     (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
11904 @@ -19,6 +19,6 @@
11905  /* This macro returns the size of a node.  Unlike "x->size",     */
11906  /* it works even if x=NULL.  The test could be avoided by using  */
11907  /* a special version of NULL which was a real node with size 0.  */
11908
11909  
11910 +
11911  #endif
11912
11913 Property changes on: src/splaytree.h
11914 ___________________________________________________________________
11915 Name: svn:eol-style
11916    + native
11917
11918 Index: src/chunk.h
11919 ===================================================================
11920 --- src/chunk.h (.../tags/lighttpd-1.4.11)      (revision 1159)
11921 +++ src/chunk.h (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
11922 @@ -6,7 +6,7 @@
11923  
11924  typedef struct chunk {
11925         enum { UNUSED_CHUNK, MEM_CHUNK, FILE_CHUNK } type;
11926 -       
11927 +
11928         buffer *mem; /* either the storage of the mem-chunk or the read-ahead buffer */
11929  
11930         struct {
11931 @@ -16,28 +16,28 @@
11932                 off_t  length; /* octets to send from the starting offset */
11933  
11934                 int    fd;
11935 -               struct { 
11936 +               struct {
11937                         char   *start; /* the start pointer of the mmap'ed area */
11938                         size_t length; /* size of the mmap'ed area */
11939 -                       off_t  offset; /* start is <n> octet away from the start of the file */
11940 +                       off_t  offset; /* start is <n> octets away from the start of the file */
11941                 } mmap;
11942  
11943 -               int is_temp; /* file is temporary and will be deleted if on cleanup */
11944 +               int is_temp; /* file is temporary and will be deleted on cleanup */
11945         } file;
11946 -       
11947 -       off_t  offset; /* octets sent from this chunk 
11948 -                         the size of the chunk is either 
11949 +
11950 +       off_t  offset; /* octets sent from this chunk
11951 +                         the size of the chunk is either
11952                           - mem-chunk: mem->used - 1
11953                           - file-chunk: file.length
11954                         */
11955 -       
11956 +
11957         struct chunk *next;
11958  } chunk;
11959  
11960  typedef struct {
11961         chunk *first;
11962         chunk *last;
11963 -       
11964 +
11965         chunk *unused;
11966         size_t unused_chunks;
11967  
11968
11969 Property changes on: src/chunk.h
11970 ___________________________________________________________________
11971 Name: svn:eol-style
11972    + native
11973
11974 Index: src/etag.c
11975 ===================================================================
11976 --- src/etag.c  (.../tags/lighttpd-1.4.11)      (revision 1159)
11977 +++ src/etag.c  (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
11978 @@ -14,19 +14,19 @@
11979         buffer_append_off_t(etag, st->st_size);
11980         buffer_append_string_len(etag, CONST_STR_LEN("-"));
11981         buffer_append_long(etag, st->st_mtime);
11982 -       
11983 +
11984         return 0;
11985  }
11986  
11987  int etag_mutate(buffer *mut, buffer *etag) {
11988         size_t h, i;
11989 -       
11990 +
11991         for (h=0, i=0; i < etag->used; ++i) h = (h<<5)^(h>>27)^(etag->ptr[i]);
11992 -       
11993 +
11994         buffer_reset(mut);
11995         buffer_copy_string_len(mut, CONST_STR_LEN("\""));
11996         buffer_append_long(mut, h);
11997         buffer_append_string_len(mut, CONST_STR_LEN("\""));
11998 -       
11999 +
12000         return 0;
12001  }
12002
12003 Property changes on: src/etag.c
12004 ___________________________________________________________________
12005 Name: svn:eol-style
12006    + native
12007
12008 Index: src/data_count.c
12009 ===================================================================
12010 --- src/data_count.c    (.../tags/lighttpd-1.4.11)      (revision 1159)
12011 +++ src/data_count.c    (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
12012 @@ -16,53 +16,53 @@
12013  
12014  static void data_count_free(data_unset *d) {
12015         data_count *ds = (data_count *)d;
12016 -       
12017 +
12018         buffer_free(ds->key);
12019 -       
12020 +
12021         free(d);
12022  }
12023  
12024  static void data_count_reset(data_unset *d) {
12025         data_count *ds = (data_count *)d;
12026 -       
12027 +
12028         buffer_reset(ds->key);
12029 -       
12030 +
12031         ds->count = 0;
12032  }
12033  
12034  static int data_count_insert_dup(data_unset *dst, data_unset *src) {
12035         data_count *ds_dst = (data_count *)dst;
12036         data_count *ds_src = (data_count *)src;
12037 -       
12038 +
12039         ds_dst->count += ds_src->count;
12040 -       
12041 +
12042         src->free(src);
12043 -       
12044 +
12045         return 0;
12046  }
12047  
12048  static void data_count_print(const data_unset *d, int depth) {
12049         data_count *ds = (data_count *)d;
12050         UNUSED(depth);
12051 -       
12052 +
12053         fprintf(stderr, "count(%d)", ds->count);
12054  }
12055  
12056  
12057  data_count *data_count_init(void) {
12058         data_count *ds;
12059 -       
12060 +
12061         ds = calloc(1, sizeof(*ds));
12062 -       
12063 +
12064         ds->key = buffer_init();
12065         ds->count = 1;
12066 -       
12067 +
12068         ds->copy = data_count_copy;
12069         ds->free = data_count_free;
12070         ds->reset = data_count_reset;
12071         ds->insert_dup = data_count_insert_dup;
12072         ds->print = data_count_print;
12073         ds->type = TYPE_COUNT;
12074 -       
12075 +
12076         return ds;
12077  }
12078
12079 Property changes on: src/data_count.c
12080 ___________________________________________________________________
12081 Name: svn:eol-style
12082    + native
12083
12084 Index: src/mod_skeleton.c
12085 ===================================================================
12086 --- src/mod_skeleton.c  (.../tags/lighttpd-1.4.11)      (revision 1159)
12087 +++ src/mod_skeleton.c  (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
12088 @@ -14,13 +14,13 @@
12089  
12090  /**
12091   * this is a skeleton for a lighttpd plugin
12092 - * 
12093 + *
12094   * just replaces every occurance of 'skeleton' by your plugin name
12095 - * 
12096 + *
12097   * e.g. in vim:
12098 - * 
12099 + *
12100   *   :%s/skeleton/myhandler/
12101 - * 
12102 + *
12103   */
12104  
12105  
12106 @@ -33,12 +33,12 @@
12107  
12108  typedef struct {
12109         PLUGIN_DATA;
12110 -       
12111 +
12112         buffer *match_buf;
12113 -       
12114 +
12115         plugin_config **config_storage;
12116 -       
12117 -       plugin_config conf; 
12118 +
12119 +       plugin_config conf;
12120  } plugin_data;
12121  
12122  typedef struct {
12123 @@ -47,36 +47,36 @@
12124  
12125  static handler_ctx * handler_ctx_init() {
12126         handler_ctx * hctx;
12127 -       
12128 +
12129         hctx = calloc(1, sizeof(*hctx));
12130 -       
12131 +
12132         return hctx;
12133  }
12134  
12135  static void handler_ctx_free(handler_ctx *hctx) {
12136 -       
12137 +
12138         free(hctx);
12139  }
12140  
12141  /* init the plugin data */
12142  INIT_FUNC(mod_skeleton_init) {
12143         plugin_data *p;
12144 -       
12145 +
12146         p = calloc(1, sizeof(*p));
12147 -       
12148 +
12149         p->match_buf = buffer_init();
12150 -       
12151 +
12152         return p;
12153  }
12154  
12155  /* detroy the plugin data */
12156  FREE_FUNC(mod_skeleton_free) {
12157         plugin_data *p = p_d;
12158 -       
12159 +
12160         UNUSED(srv);
12161  
12162         if (!p) return HANDLER_GO_ON;
12163 -       
12164 +
12165         if (p->config_storage) {
12166                 size_t i;
12167  
12168 @@ -84,18 +84,18 @@
12169                         plugin_config *s = p->config_storage[i];
12170  
12171                         if (!s) continue;
12172 -                       
12173 +
12174                         array_free(s->match);
12175 -                       
12176 +
12177                         free(s);
12178                 }
12179                 free(p->config_storage);
12180         }
12181 -       
12182 +
12183         buffer_free(p->match_buf);
12184 -       
12185 +
12186         free(p);
12187 -       
12188 +
12189         return HANDLER_GO_ON;
12190  }
12191  
12192 @@ -104,91 +104,88 @@
12193  SETDEFAULTS_FUNC(mod_skeleton_set_defaults) {
12194         plugin_data *p = p_d;
12195         size_t i = 0;
12196 -       
12197 -       config_values_t cv[] = { 
12198 +
12199 +       config_values_t cv[] = {
12200                 { "skeleton.array",             NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
12201                 { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
12202         };
12203 -       
12204 +
12205         if (!p) return HANDLER_ERROR;
12206 -       
12207 +
12208         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
12209 -       
12210 +
12211         for (i = 0; i < srv->config_context->used; i++) {
12212                 plugin_config *s;
12213 -               
12214 +
12215                 s = calloc(1, sizeof(plugin_config));
12216                 s->match    = array_init();
12217 -               
12218 +
12219                 cv[0].destination = s->match;
12220 -               
12221 +
12222                 p->config_storage[i] = s;
12223 -       
12224 +
12225                 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
12226                         return HANDLER_ERROR;
12227                 }
12228         }
12229 -       
12230 +
12231         return HANDLER_GO_ON;
12232  }
12233  
12234 -#define PATCH(x) \
12235 -       p->conf.x = s->x;
12236  static int mod_skeleton_patch_connection(server *srv, connection *con, plugin_data *p) {
12237         size_t i, j;
12238         plugin_config *s = p->config_storage[0];
12239 -       
12240 -       PATCH(match);
12241 -       
12242 +
12243 +       PATCH_OPTION(match);
12244 +
12245         /* skip the first, the global context */
12246         for (i = 1; i < srv->config_context->used; i++) {
12247                 data_config *dc = (data_config *)srv->config_context->data[i];
12248                 s = p->config_storage[i];
12249 -               
12250 +
12251                 /* condition didn't match */
12252                 if (!config_check_cond(srv, con, dc)) continue;
12253 -               
12254 +
12255                 /* merge config */
12256                 for (j = 0; j < dc->value->used; j++) {
12257                         data_unset *du = dc->value->data[j];
12258 -                       
12259 +
12260                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("skeleton.array"))) {
12261 -                               PATCH(match);
12262 +                               PATCH_OPTION(match);
12263                         }
12264                 }
12265         }
12266 -       
12267 +
12268         return 0;
12269  }
12270 -#undef PATCH
12271  
12272  URIHANDLER_FUNC(mod_skeleton_uri_handler) {
12273         plugin_data *p = p_d;
12274         int s_len;
12275         size_t k, i;
12276 -       
12277 +
12278         UNUSED(srv);
12279  
12280         if (con->uri.path->used == 0) return HANDLER_GO_ON;
12281 -       
12282 +
12283         mod_skeleton_patch_connection(srv, con, p);
12284  
12285         s_len = con->uri.path->used - 1;
12286 -       
12287 +
12288         for (k = 0; k < p->conf.match->used; k++) {
12289                 data_string *ds = (data_string *)p->conf.match->data[k];
12290                 int ct_len = ds->value->used - 1;
12291 -               
12292 +
12293                 if (ct_len > s_len) continue;
12294                 if (ds->value->used == 0) continue;
12295 -               
12296 +
12297                 if (0 == strncmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) {
12298                         con->http_status = 403;
12299 -       
12300 +
12301                         return HANDLER_FINISHED;
12302                 }
12303         }
12304 -       
12305 +
12306         /* not found */
12307         return HANDLER_GO_ON;
12308  }
12309 @@ -198,13 +195,13 @@
12310  int mod_skeleton_plugin_init(plugin *p) {
12311         p->version     = LIGHTTPD_VERSION_ID;
12312         p->name        = buffer_init_string("skeleton");
12313 -       
12314 +
12315         p->init        = mod_skeleton_init;
12316         p->handle_uri_clean  = mod_skeleton_uri_handler;
12317         p->set_defaults  = mod_skeleton_set_defaults;
12318         p->cleanup     = mod_skeleton_free;
12319 -       
12320 +
12321         p->data        = NULL;
12322 -       
12323 +
12324         return 0;
12325  }
12326
12327 Property changes on: src/mod_skeleton.c
12328 ___________________________________________________________________
12329 Name: svn:eol-style
12330    + native
12331
12332 Index: src/mod_scgi.c
12333 ===================================================================
12334 --- src/mod_scgi.c      (.../tags/lighttpd-1.4.11)      (revision 1159)
12335 +++ src/mod_scgi.c      (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
12336 @@ -1,5 +1,4 @@
12337  #include <sys/types.h>
12338 -#include <unistd.h>
12339  #include <errno.h>
12340  #include <fcntl.h>
12341  #include <string.h>
12342 @@ -30,8 +29,10 @@
12343  #endif
12344  
12345  #include "sys-socket.h"
12346 +#include "sys-files.h"
12347 +#include "sys-strings.h"
12348 +#include "sys-process.h"
12349  
12350 -
12351  #ifndef UNIX_PATH_MAX
12352  # define UNIX_PATH_MAX 108
12353  #endif
12354 @@ -46,30 +47,29 @@
12355  enum {EOL_UNSET, EOL_N, EOL_RN};
12356  
12357  /*
12358 - * 
12359 + *
12360   * TODO:
12361 - * 
12362 + *
12363   * - add timeout for a connect to a non-scgi process
12364   *   (use state_timestamp + state)
12365 - * 
12366 + *
12367   */
12368  
12369  typedef struct scgi_proc {
12370         size_t id; /* id will be between 1 and max_procs */
12371         buffer *socket; /* config.socket + "-" + id */
12372         unsigned port;  /* config.port + pno */
12373 -       
12374 +
12375         pid_t pid;   /* PID of the spawned process (0 if not spawned locally) */
12376  
12377 -
12378         size_t load; /* number of requests waiting on this process */
12379  
12380         time_t last_used; /* see idle_timeout */
12381         size_t requests;  /* see max_requests */
12382         struct scgi_proc *prev, *next; /* see first */
12383 -       
12384 +
12385         time_t disable_ts; /* replace by host->something */
12386 -       
12387 +
12388         int is_local;
12389  
12390         enum { PROC_STATE_UNSET,            /* init-phase */
12391 @@ -78,7 +78,7 @@
12392                         PROC_STATE_KILLED,  /* was killed as we don't have the load anymore */
12393                         PROC_STATE_DIED,    /* marked as dead, should be restarted */
12394                         PROC_STATE_DISABLED /* proc disabled as it resulted in an error */
12395 -       } state; 
12396 +       } state;
12397  } scgi_proc;
12398  
12399  typedef struct {
12400 @@ -86,20 +86,20 @@
12401          * sorted by lowest load
12402          *
12403          * whenever a job is done move it up in the list
12404 -        * until it is sorted, move it down as soon as the 
12405 +        * until it is sorted, move it down as soon as the
12406          * job is started
12407          */
12408 -       scgi_proc *first; 
12409 -       scgi_proc *unused_procs; 
12410 +       scgi_proc *first;
12411 +       scgi_proc *unused_procs;
12412  
12413 -       /* 
12414 +       /*
12415          * spawn at least min_procs, at max_procs.
12416          *
12417 -        * as soon as the load of the first entry 
12418 +        * as soon as the load of the first entry
12419          * is max_load_per_proc we spawn a new one
12420 -        * and add it to the first entry and give it 
12421 +        * and add it to the first entry and give it
12422          * the load
12423 -        * 
12424 +        *
12425          */
12426  
12427         unsigned short min_procs;
12428 @@ -111,44 +111,44 @@
12429  
12430         /*
12431          * kick the process from the list if it was not
12432 -        * used for idle_timeout until min_procs is 
12433 +        * used for idle_timeout until min_procs is
12434          * reached. this helps to get the processlist
12435          * small again we had a small peak load.
12436          *
12437          */
12438 -       
12439 +
12440         unsigned short idle_timeout;
12441 -       
12442 +
12443         /*
12444          * time after a disabled remote connection is tried to be re-enabled
12445 -        * 
12446 -        * 
12447 +        *
12448 +        *
12449          */
12450 -       
12451 +
12452         unsigned short disable_time;
12453  
12454         /*
12455          * same scgi processes get a little bit larger
12456 -        * than wanted. max_requests_per_proc kills a 
12457 +        * than wanted. max_requests_per_proc kills a
12458          * process after a number of handled requests.
12459          *
12460          */
12461         size_t max_requests_per_proc;
12462 -       
12463  
12464 +
12465         /* config */
12466  
12467 -       /* 
12468 -        * host:port 
12469 +       /*
12470 +        * host:port
12471          *
12472 -        * if host is one of the local IP adresses the 
12473 +        * if host is one of the local IP adresses the
12474          * whole connection is local
12475          *
12476          * if tcp/ip should be used host AND port have
12477 -        * to be specified 
12478 -        * 
12479 -        */ 
12480 -       buffer *host; 
12481 +        * to be specified
12482 +        *
12483 +        */
12484 +       buffer *host;
12485         unsigned short port;
12486  
12487         /*
12488 @@ -161,7 +161,7 @@
12489          */
12490         buffer *unixsocket;
12491  
12492 -       /* if socket is local we can start the scgi 
12493 +       /* if socket is local we can start the scgi
12494          * process ourself
12495          *
12496          * bin-path is the path to the binary
12497 @@ -169,19 +169,19 @@
12498          * check min_procs and max_procs for the number
12499          * of process to start-up
12500          */
12501 -       buffer *bin_path; 
12502 -       
12503 -       /* bin-path is set bin-environment is taken to 
12504 +       buffer *bin_path;
12505 +
12506 +       /* bin-path is set bin-environment is taken to
12507          * create the environement before starting the
12508          * FastCGI process
12509 -        * 
12510 +        *
12511          */
12512         array *bin_env;
12513 -       
12514 +
12515         array *bin_env_copy;
12516 -       
12517 +
12518         /*
12519 -        * docroot-translation between URL->phys and the 
12520 +        * docroot-translation between URL->phys and the
12521          * remote host
12522          *
12523          * reasons:
12524 @@ -192,7 +192,7 @@
12525         buffer *docroot;
12526  
12527         /*
12528 -        * check_local tell you if the phys file is stat()ed 
12529 +        * check_local tell you if the phys file is stat()ed
12530          * or not. FastCGI doesn't care if the service is
12531          * remote. If the web-server side doesn't contain
12532          * the scgi-files we should not stat() for them
12533 @@ -202,33 +202,33 @@
12534  
12535         /*
12536          * append PATH_INFO to SCRIPT_FILENAME
12537 -        * 
12538 +        *
12539          * php needs this if cgi.fix_pathinfo is provied
12540 -        * 
12541 +        *
12542          */
12543 -       
12544 +
12545         ssize_t load; /* replace by host->load */
12546  
12547         size_t max_id; /* corresponds most of the time to
12548         num_procs.
12549 -       
12550 +
12551         only if a process is killed max_id waits for the process itself
12552         to die and decrements its afterwards */
12553  } scgi_extension_host;
12554  
12555  /*
12556   * one extension can have multiple hosts assigned
12557 - * one host can spawn additional processes on the same 
12558 + * one host can spawn additional processes on the same
12559   *   socket (if we control it)
12560   *
12561   * ext -> host -> procs
12562   *    1:n     1:n
12563   *
12564 - * if the scgi process is remote that whole goes down 
12565 + * if the scgi process is remote that whole goes down
12566   * to
12567   *
12568   * ext -> host -> procs
12569 - *    1:n     1:1 
12570 + *    1:n     1:1
12571   *
12572   * in case of PHP and FCGI_CHILDREN we have again a procs
12573   * but we don't control it directly.
12574 @@ -239,7 +239,7 @@
12575         buffer *key; /* like .php */
12576  
12577         scgi_extension_host **hosts;
12578 -       
12579 +
12580         size_t used;
12581         size_t size;
12582  } scgi_extension;
12583 @@ -253,14 +253,14 @@
12584  
12585  
12586  typedef struct {
12587 -       scgi_exts *exts; 
12588 -       
12589 +       scgi_exts *exts;
12590 +
12591         int debug;
12592  } plugin_config;
12593  
12594  typedef struct {
12595         char **ptr;
12596 -       
12597 +
12598         size_t size;
12599         size_t used;
12600  } char_array;
12601 @@ -268,52 +268,51 @@
12602  /* generic plugin data, shared between all connections */
12603  typedef struct {
12604         PLUGIN_DATA;
12605 -       
12606 +
12607         buffer *scgi_env;
12608 -       
12609 +
12610         buffer *path;
12611         buffer *parse_response;
12612 -       
12613 +
12614         plugin_config **config_storage;
12615 -       
12616 +
12617         plugin_config conf; /* this is only used as long as no handler_ctx is setup */
12618  } plugin_data;
12619  
12620  /* connection specific data */
12621 -typedef enum { FCGI_STATE_INIT, FCGI_STATE_CONNECT, FCGI_STATE_PREPARE_WRITE, 
12622 -               FCGI_STATE_WRITE, FCGI_STATE_READ 
12623 +typedef enum { FCGI_STATE_INIT, FCGI_STATE_CONNECT, FCGI_STATE_PREPARE_WRITE,
12624 +               FCGI_STATE_WRITE, FCGI_STATE_READ
12625  } scgi_connection_state_t;
12626  
12627  typedef struct {
12628 -       buffer  *response; 
12629 +       buffer  *response;
12630         size_t   response_len;
12631         int      response_type;
12632         int      response_padding;
12633 -       
12634 +
12635         scgi_proc *proc;
12636         scgi_extension_host *host;
12637 -       
12638 +
12639         scgi_connection_state_t state;
12640         time_t   state_timestamp;
12641 -       
12642 +
12643         int      reconnects; /* number of reconnect attempts */
12644 -       
12645 +
12646         read_buffer *rb;
12647         chunkqueue *wb;
12648 -       
12649 +
12650         buffer   *response_header;
12651 -       
12652 +
12653         int       delayed;   /* flag to mark that the connect() is delayed */
12654 -       
12655 +
12656         size_t    request_id;
12657         int       fd;        /* fd to the scgi process */
12658         int       fde_ndx;   /* index into the fd-event buffer */
12659 -
12660         pid_t     pid;
12661         int       got_proc;
12662 -       
12663 +
12664         plugin_config conf;
12665 -       
12666 +
12667         connection *remote_conn;  /* dumb pointer */
12668         plugin_data *plugin_data; /* dumb pointer */
12669  } handler_ctx;
12670 @@ -328,28 +327,28 @@
12671  
12672  static handler_ctx * handler_ctx_init() {
12673         handler_ctx * hctx;
12674 -       
12675 +
12676         hctx = calloc(1, sizeof(*hctx));
12677         assert(hctx);
12678 -       
12679 +
12680         hctx->fde_ndx = -1;
12681 -       
12682 +
12683         hctx->response = buffer_init();
12684         hctx->response_header = buffer_init();
12685 -       
12686 +
12687         hctx->request_id = 0;
12688         hctx->state = FCGI_STATE_INIT;
12689         hctx->proc = NULL;
12690 -       
12691 +
12692         hctx->response_len = 0;
12693         hctx->response_type = 0;
12694         hctx->response_padding = 0;
12695         hctx->fd = -1;
12696 -       
12697 +
12698         hctx->reconnects = 0;
12699  
12700         hctx->wb = chunkqueue_init();
12701 -       
12702 +
12703         return hctx;
12704  }
12705  
12706 @@ -358,12 +357,12 @@
12707         buffer_free(hctx->response_header);
12708  
12709         chunkqueue_free(hctx->wb);
12710 -       
12711 +
12712         if (hctx->rb) {
12713                 if (hctx->rb->ptr) free(hctx->rb->ptr);
12714                 free(hctx->rb);
12715         }
12716 -       
12717 +
12718         free(hctx);
12719  }
12720  
12721 @@ -372,20 +371,20 @@
12722  
12723         f = calloc(1, sizeof(*f));
12724         f->socket = buffer_init();
12725 -       
12726 +
12727         f->prev = NULL;
12728         f->next = NULL;
12729 -       
12730 +
12731         return f;
12732  }
12733  
12734  void scgi_process_free(scgi_proc *f) {
12735         if (!f) return;
12736 -       
12737 +
12738         scgi_process_free(f->next);
12739 -       
12740 +
12741         buffer_free(f->socket);
12742 -       
12743 +
12744         free(f);
12745  }
12746  
12747 @@ -400,62 +399,62 @@
12748         f->bin_path = buffer_init();
12749         f->bin_env = array_init();
12750         f->bin_env_copy = array_init();
12751 -       
12752 +
12753         return f;
12754  }
12755  
12756  void scgi_host_free(scgi_extension_host *h) {
12757         if (!h) return;
12758 -       
12759 +
12760         buffer_free(h->host);
12761         buffer_free(h->unixsocket);
12762         buffer_free(h->docroot);
12763         buffer_free(h->bin_path);
12764         array_free(h->bin_env);
12765         array_free(h->bin_env_copy);
12766 -       
12767 +
12768         scgi_process_free(h->first);
12769         scgi_process_free(h->unused_procs);
12770 -       
12771 +
12772         free(h);
12773 -       
12774 +
12775  }
12776  
12777  scgi_exts *scgi_extensions_init() {
12778         scgi_exts *f;
12779  
12780         f = calloc(1, sizeof(*f));
12781 -       
12782 +
12783         return f;
12784  }
12785  
12786  void scgi_extensions_free(scgi_exts *f) {
12787         size_t i;
12788 -       
12789 +
12790         if (!f) return;
12791 -       
12792 +
12793         for (i = 0; i < f->used; i++) {
12794                 scgi_extension *fe;
12795                 size_t j;
12796 -               
12797 +
12798                 fe = f->exts[i];
12799 -               
12800 +
12801                 for (j = 0; j < fe->used; j++) {
12802                         scgi_extension_host *h;
12803 -                       
12804 +
12805                         h = fe->hosts[j];
12806 -                       
12807 +
12808                         scgi_host_free(h);
12809                 }
12810 -               
12811 +
12812                 buffer_free(fe->key);
12813                 free(fe->hosts);
12814 -               
12815 +
12816                 free(fe);
12817         }
12818 -       
12819 +
12820         free(f->exts);
12821 -       
12822 +
12823         free(f);
12824  }
12825  
12826 @@ -504,99 +503,103 @@
12827                 assert(fe->hosts);
12828         }
12829  
12830 -       fe->hosts[fe->used++] = fh; 
12831 +       fe->hosts[fe->used++] = fh;
12832  
12833         return 0;
12834 -       
12835 +
12836  }
12837  
12838  INIT_FUNC(mod_scgi_init) {
12839         plugin_data *p;
12840 -       
12841 +
12842         p = calloc(1, sizeof(*p));
12843 -       
12844 +
12845         p->scgi_env = buffer_init();
12846 -       
12847 +
12848         p->path = buffer_init();
12849         p->parse_response = buffer_init();
12850 -       
12851 +
12852         return p;
12853  }
12854  
12855  
12856  FREE_FUNC(mod_scgi_free) {
12857         plugin_data *p = p_d;
12858 -       
12859 +
12860         UNUSED(srv);
12861  
12862         buffer_free(p->scgi_env);
12863         buffer_free(p->path);
12864         buffer_free(p->parse_response);
12865 -       
12866 +
12867         if (p->config_storage) {
12868                 size_t i, j, n;
12869                 for (i = 0; i < srv->config_context->used; i++) {
12870                         plugin_config *s = p->config_storage[i];
12871                         scgi_exts *exts;
12872 -                       
12873 +
12874                         if (!s) continue;
12875 -                       
12876 +
12877                         exts = s->exts;
12878  
12879                         for (j = 0; j < exts->used; j++) {
12880                                 scgi_extension *ex;
12881 -                               
12882 +
12883                                 ex = exts->exts[j];
12884 -                               
12885 +
12886                                 for (n = 0; n < ex->used; n++) {
12887                                         scgi_proc *proc;
12888                                         scgi_extension_host *host;
12889 -                                       
12890 +
12891                                         host = ex->hosts[n];
12892 -                                       
12893 +
12894                                         for (proc = host->first; proc; proc = proc->next) {
12895 +#ifndef _WIN32
12896                                                 if (proc->pid != 0) kill(proc->pid, SIGTERM);
12897 -                                               
12898 -                                               if (proc->is_local && 
12899 +#endif
12900 +
12901 +                                               if (proc->is_local &&
12902                                                     !buffer_is_empty(proc->socket)) {
12903                                                         unlink(proc->socket->ptr);
12904                                                 }
12905                                         }
12906 -                                       
12907 +
12908                                         for (proc = host->unused_procs; proc; proc = proc->next) {
12909 +#ifndef _WIN32
12910                                                 if (proc->pid != 0) kill(proc->pid, SIGTERM);
12911 -                                               
12912 -                                               if (proc->is_local && 
12913 +#endif
12914 +
12915 +                                               if (proc->is_local &&
12916                                                     !buffer_is_empty(proc->socket)) {
12917                                                         unlink(proc->socket->ptr);
12918                                                 }
12919                                         }
12920                                 }
12921                         }
12922 -                       
12923 +
12924                         scgi_extensions_free(s->exts);
12925 -                       
12926 +
12927                         free(s);
12928                 }
12929                 free(p->config_storage);
12930         }
12931 -       
12932 +
12933         free(p);
12934 -       
12935 +
12936         return HANDLER_GO_ON;
12937  }
12938  
12939  static int env_add(char_array *env, const char *key, size_t key_len, const char *val, size_t val_len) {
12940         char *dst;
12941 -       
12942 +
12943         if (!key || !val) return -1;
12944 -       
12945 +
12946         dst = malloc(key_len + val_len + 3);
12947         memcpy(dst, key, key_len);
12948         dst[key_len] = '=';
12949         /* add the \0 from the value */
12950         memcpy(dst + key_len + 1, val, val_len + 1);
12951 -       
12952 +
12953         if (env->size == 0) {
12954                 env->size = 16;
12955                 env->ptr = malloc(env->size * sizeof(*env->ptr));
12956 @@ -604,13 +607,13 @@
12957                 env->size += 16;
12958                 env->ptr = realloc(env->ptr, env->size * sizeof(*env->ptr));
12959         }
12960 -       
12961 +
12962         env->ptr[env->used++] = dst;
12963 -       
12964 +
12965         return 0;
12966  }
12967  
12968 -static int scgi_spawn_connection(server *srv, 
12969 +static int scgi_spawn_connection(server *srv,
12970                                  plugin_data *p,
12971                                  scgi_extension_host *host,
12972                                  scgi_proc *proc) {
12973 @@ -622,31 +625,27 @@
12974  #endif
12975         struct sockaddr_in scgi_addr_in;
12976         struct sockaddr *scgi_addr;
12977 -       
12978 +
12979         socklen_t servlen;
12980 -       
12981 +
12982  #ifndef HAVE_FORK
12983         return -1;
12984  #endif
12985 -       
12986 +
12987         if (p->conf.debug) {
12988                 log_error_write(srv, __FILE__, __LINE__, "sdb",
12989                                 "new proc, socket:", proc->port, proc->socket);
12990         }
12991 -               
12992 +
12993         if (!buffer_is_empty(proc->socket)) {
12994                 memset(&scgi_addr, 0, sizeof(scgi_addr));
12995 -               
12996 +
12997  #ifdef HAVE_SYS_UN_H
12998                 scgi_addr_un.sun_family = AF_UNIX;
12999                 strcpy(scgi_addr_un.sun_path, proc->socket->ptr);
13000 -               
13001 -#ifdef SUN_LEN
13002 +
13003                 servlen = SUN_LEN(&scgi_addr_un);
13004 -#else
13005 -               /* stevens says: */
13006 -               servlen = proc->socket->used + sizeof(scgi_addr_un.sun_family);
13007 -#endif
13008 +
13009                 socket_type = AF_UNIX;
13010                 scgi_addr = (struct sockaddr *) &scgi_addr_un;
13011  #else
13012 @@ -656,115 +655,115 @@
13013  #endif
13014         } else {
13015                 scgi_addr_in.sin_family = AF_INET;
13016 -               
13017 +
13018                 if (buffer_is_empty(host->host)) {
13019                         scgi_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
13020                 } else {
13021                         struct hostent *he;
13022 -                       
13023 +
13024                         /* set a usefull default */
13025                         scgi_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
13026 -                       
13027 -                       
13028 +
13029 +
13030                         if (NULL == (he = gethostbyname(host->host->ptr))) {
13031 -                               log_error_write(srv, __FILE__, __LINE__, 
13032 -                                               "sdb", "gethostbyname failed: ", 
13033 +                               log_error_write(srv, __FILE__, __LINE__,
13034 +                                               "sdb", "gethostbyname failed: ",
13035                                                 h_errno, host->host);
13036                                 return -1;
13037                         }
13038 -                       
13039 +
13040                         if (he->h_addrtype != AF_INET) {
13041                                 log_error_write(srv, __FILE__, __LINE__, "sd", "addr-type != AF_INET: ", he->h_addrtype);
13042                                 return -1;
13043                         }
13044 -                       
13045 +
13046                         if (he->h_length != sizeof(struct in_addr)) {
13047                                 log_error_write(srv, __FILE__, __LINE__, "sd", "addr-length != sizeof(in_addr): ", he->h_length);
13048                                 return -1;
13049                         }
13050 -                       
13051 +
13052                         memcpy(&(scgi_addr_in.sin_addr.s_addr), he->h_addr_list[0], he->h_length);
13053 -                       
13054 +
13055                 }
13056                 scgi_addr_in.sin_port = htons(proc->port);
13057                 servlen = sizeof(scgi_addr_in);
13058 -               
13059 +
13060                 socket_type = AF_INET;
13061                 scgi_addr = (struct sockaddr *) &scgi_addr_in;
13062         }
13063 -       
13064 +
13065         if (-1 == (scgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
13066 -               log_error_write(srv, __FILE__, __LINE__, "ss", 
13067 +               log_error_write(srv, __FILE__, __LINE__, "ss",
13068                                 "failed:", strerror(errno));
13069                 return -1;
13070         }
13071 -       
13072 +
13073         if (-1 == connect(scgi_fd, scgi_addr, servlen)) {
13074                 /* server is not up, spawn in  */
13075                 pid_t child;
13076                 int val;
13077 -               
13078 +
13079                 if (!buffer_is_empty(proc->socket)) {
13080                         unlink(proc->socket->ptr);
13081                 }
13082 -               
13083 +
13084                 close(scgi_fd);
13085 -               
13086 +
13087                 /* reopen socket */
13088                 if (-1 == (scgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
13089 -                       log_error_write(srv, __FILE__, __LINE__, "ss", 
13090 +                       log_error_write(srv, __FILE__, __LINE__, "ss",
13091                                 "socket failed:", strerror(errno));
13092                         return -1;
13093                 }
13094 -               
13095 +
13096                 val = 1;
13097                 if (setsockopt(scgi_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
13098 -                       log_error_write(srv, __FILE__, __LINE__, "ss", 
13099 +                       log_error_write(srv, __FILE__, __LINE__, "ss",
13100                                         "socketsockopt failed:", strerror(errno));
13101                         return -1;
13102                 }
13103 -               
13104 +
13105                 /* create socket */
13106                 if (-1 == bind(scgi_fd, scgi_addr, servlen)) {
13107 -                       log_error_write(srv, __FILE__, __LINE__, "sbds", 
13108 -                               "bind failed for:", 
13109 -                               proc->socket, 
13110 -                               proc->port, 
13111 +                       log_error_write(srv, __FILE__, __LINE__, "sbds",
13112 +                               "bind failed for:",
13113 +                               proc->socket,
13114 +                               proc->port,
13115                                 strerror(errno));
13116                         return -1;
13117                 }
13118 -               
13119 +
13120                 if (-1 == listen(scgi_fd, 1024)) {
13121 -                       log_error_write(srv, __FILE__, __LINE__, "ss", 
13122 +                       log_error_write(srv, __FILE__, __LINE__, "ss",
13123                                 "listen failed:", strerror(errno));
13124                         return -1;
13125                 }
13126 -               
13127 -#ifdef HAVE_FORK       
13128 +
13129 +#ifdef HAVE_FORK
13130                 switch ((child = fork())) {
13131                 case 0: {
13132                         buffer *b;
13133                         size_t i = 0;
13134                         int fd = 0;
13135                         char_array env;
13136 -                       
13137 -                       
13138 +
13139 +
13140                         /* create environment */
13141                         env.ptr = NULL;
13142                         env.size = 0;
13143                         env.used = 0;
13144 -                       
13145 +
13146                         /* we don't need the client socket */
13147                         for (fd = 3; fd < 256; fd++) {
13148                                 if (fd != 2 && fd != scgi_fd) close(fd);
13149                         }
13150 -                       
13151 +
13152                         /* build clean environment */
13153                         if (host->bin_env_copy->used) {
13154                                 for (i = 0; i < host->bin_env_copy->used; i++) {
13155                                         data_string *ds = (data_string *)host->bin_env_copy->data[i];
13156                                         char *ge;
13157 -                                       
13158 +
13159                                         if (NULL != (ge = getenv(ds->value->ptr))) {
13160                                                 env_add(&env, CONST_BUF_LEN(ds->value), ge, strlen(ge));
13161                                         }
13162 @@ -772,44 +771,44 @@
13163                         } else {
13164                                 for (i = 0; environ[i]; i++) {
13165                                         char *eq;
13166 -                                       
13167 +
13168                                         if (NULL != (eq = strchr(environ[i], '='))) {
13169                                                 env_add(&env, environ[i], eq - environ[i], eq+1, strlen(eq+1));
13170                                         }
13171                                 }
13172                         }
13173 -                       
13174 +
13175                         /* create environment */
13176                         for (i = 0; i < host->bin_env->used; i++) {
13177                                 data_string *ds = (data_string *)host->bin_env->data[i];
13178 -                               
13179 +
13180                                 env_add(&env, CONST_BUF_LEN(ds->key), CONST_BUF_LEN(ds->value));
13181                         }
13182 -                       
13183 +
13184                         for (i = 0; i < env.used; i++) {
13185                                 /* search for PHP_FCGI_CHILDREN */
13186                                 if (0 == strncmp(env.ptr[i], "PHP_FCGI_CHILDREN=", sizeof("PHP_FCGI_CHILDREN=") - 1)) break;
13187                         }
13188 -                       
13189 +
13190                         /* not found, add a default */
13191                         if (i == env.used) {
13192                                 env_add(&env, CONST_STR_LEN("PHP_FCGI_CHILDREN"), CONST_STR_LEN("1"));
13193                         }
13194 -                       
13195 +
13196                         env.ptr[env.used] = NULL;
13197 -                       
13198 +
13199                         b = buffer_init();
13200                         buffer_copy_string(b, "exec ");
13201                         buffer_append_string_buffer(b, host->bin_path);
13202 -                       
13203 +
13204                         /* exec the cgi */
13205                         execle("/bin/sh", "sh", "-c", b->ptr, NULL, env.ptr);
13206 -                       
13207 -                       log_error_write(srv, __FILE__, __LINE__, "sbs", 
13208 +
13209 +                       log_error_write(srv, __FILE__, __LINE__, "sbs",
13210                                         "execl failed for:", host->bin_path, strerror(errno));
13211 -                       
13212 +
13213                         exit(errno);
13214 -                       
13215 +
13216                         break;
13217                 }
13218                 case -1:
13219 @@ -817,32 +816,32 @@
13220                         break;
13221                 default:
13222                         /* father */
13223 -                       
13224 +
13225                         /* wait */
13226                         select(0, NULL, NULL, NULL, &tv);
13227 -                       
13228 +
13229                         switch (waitpid(child, &status, WNOHANG)) {
13230                         case 0:
13231                                 /* child still running after timeout, good */
13232                                 break;
13233                         case -1:
13234                                 /* no PID found ? should never happen */
13235 -                               log_error_write(srv, __FILE__, __LINE__, "ss", 
13236 +                               log_error_write(srv, __FILE__, __LINE__, "ss",
13237                                                 "pid not found:", strerror(errno));
13238                                 return -1;
13239                         default:
13240                                 /* the child should not terminate at all */
13241                                 if (WIFEXITED(status)) {
13242 -                                       log_error_write(srv, __FILE__, __LINE__, "sd", 
13243 -                                                       "child exited (is this a SCGI binary ?):", 
13244 +                                       log_error_write(srv, __FILE__, __LINE__, "sd",
13245 +                                                       "child exited (is this a SCGI binary ?):",
13246                                                         WEXITSTATUS(status));
13247                                 } else if (WIFSIGNALED(status)) {
13248 -                                       log_error_write(srv, __FILE__, __LINE__, "sd", 
13249 -                                                       "child signaled:", 
13250 +                                       log_error_write(srv, __FILE__, __LINE__, "sd",
13251 +                                                       "child signaled:",
13252                                                         WTERMSIG(status));
13253                                 } else {
13254 -                                       log_error_write(srv, __FILE__, __LINE__, "sd", 
13255 -                                                       "child died somehow:", 
13256 +                                       log_error_write(srv, __FILE__, __LINE__, "sd",
13257 +                                                       "child died somehow:",
13258                                                         status);
13259                                 }
13260                                 return -1;
13261 @@ -852,26 +851,26 @@
13262                         proc->pid = child;
13263                         proc->last_used = srv->cur_ts;
13264                         proc->is_local = 1;
13265 -                                               
13266 +
13267                         break;
13268                 }
13269  #endif
13270         } else {
13271                 proc->is_local = 0;
13272                 proc->pid = 0;
13273 -               
13274 +
13275                 if (p->conf.debug) {
13276                         log_error_write(srv, __FILE__, __LINE__, "sb",
13277                                         "(debug) socket is already used, won't spawn:",
13278                                         proc->socket);
13279                 }
13280         }
13281 -       
13282 +
13283         proc->state = PROC_STATE_RUNNING;
13284         host->active_procs++;
13285 -       
13286 +
13287         close(scgi_fd);
13288 -       
13289 +
13290         return 0;
13291  }
13292  
13293 @@ -880,89 +879,89 @@
13294         plugin_data *p = p_d;
13295         data_unset *du;
13296         size_t i = 0;
13297 -       
13298 -       config_values_t cv[] = { 
13299 +
13300 +       config_values_t cv[] = {
13301                 { "scgi.server",              NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
13302                 { "scgi.debug",               NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
13303                 { NULL,                          NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
13304         };
13305 -       
13306 +
13307         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
13308 -       
13309 +
13310         for (i = 0; i < srv->config_context->used; i++) {
13311                 plugin_config *s;
13312                 array *ca;
13313 -               
13314 +
13315                 s = malloc(sizeof(plugin_config));
13316                 s->exts          = scgi_extensions_init();
13317                 s->debug         = 0;
13318 -               
13319 +
13320                 cv[0].destination = s->exts;
13321                 cv[1].destination = &(s->debug);
13322 -               
13323 +
13324                 p->config_storage[i] = s;
13325                 ca = ((data_config *)srv->config_context->data[i])->value;
13326 -       
13327 +
13328                 if (0 != config_insert_values_global(srv, ca, cv)) {
13329                         return HANDLER_ERROR;
13330                 }
13331 -               
13332 -               /* 
13333 +
13334 +               /*
13335                  * <key> = ( ... )
13336                  */
13337 -               
13338 +
13339                 if (NULL != (du = array_get_element(ca, "scgi.server"))) {
13340                         size_t j;
13341                         data_array *da = (data_array *)du;
13342 -                       
13343 +
13344                         if (du->type != TYPE_ARRAY) {
13345 -                               log_error_write(srv, __FILE__, __LINE__, "sss", 
13346 +                               log_error_write(srv, __FILE__, __LINE__, "sss",
13347                                                 "unexpected type for key: ", "scgi.server", "array of strings");
13348 -                               
13349 +
13350                                 return HANDLER_ERROR;
13351                         }
13352 -                       
13353 -                       
13354 -                       /* 
13355 -                        * scgi.server = ( "<ext>" => ( ... ), 
13356 +
13357 +
13358 +                       /*
13359 +                        * scgi.server = ( "<ext>" => ( ... ),
13360                          *                    "<ext>" => ( ... ) )
13361                          */
13362 -                       
13363 +
13364                         for (j = 0; j < da->value->used; j++) {
13365                                 size_t n;
13366                                 data_array *da_ext = (data_array *)da->value->data[j];
13367 -                               
13368 +
13369                                 if (da->value->data[j]->type != TYPE_ARRAY) {
13370 -                                       log_error_write(srv, __FILE__, __LINE__, "sssbs", 
13371 -                                                       "unexpected type for key: ", "scgi.server", 
13372 +                                       log_error_write(srv, __FILE__, __LINE__, "sssbs",
13373 +                                                       "unexpected type for key: ", "scgi.server",
13374                                                         "[", da->value->data[j]->key, "](string)");
13375 -                                       
13376 +
13377                                         return HANDLER_ERROR;
13378                                 }
13379 -                               
13380 -                               /* 
13381 -                                * da_ext->key == name of the extension 
13382 +
13383 +                               /*
13384 +                                * da_ext->key == name of the extension
13385                                  */
13386 -                               
13387 -                               /* 
13388 -                                * scgi.server = ( "<ext>" => 
13389 -                                *                     ( "<host>" => ( ... ), 
13390 +
13391 +                               /*
13392 +                                * scgi.server = ( "<ext>" =>
13393 +                                *                     ( "<host>" => ( ... ),
13394                                  *                       "<host>" => ( ... )
13395 -                                *                     ), 
13396 +                                *                     ),
13397                                  *                    "<ext>" => ... )
13398                                  */
13399 -                                       
13400 +
13401                                 for (n = 0; n < da_ext->value->used; n++) {
13402                                         data_array *da_host = (data_array *)da_ext->value->data[n];
13403 -                                       
13404 +
13405                                         scgi_extension_host *df;
13406 -                                       
13407 -                                       config_values_t fcv[] = { 
13408 +
13409 +                                       config_values_t fcv[] = {
13410                                                 { "host",              NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
13411                                                 { "docroot",           NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
13412                                                 { "socket",            NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 2 */
13413                                                 { "bin-path",          NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 3 */
13414 -                                               
13415 +
13416                                                 { "check-local",       NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },      /* 4 */
13417                                                 { "port",              NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 5 */
13418                                                 { "min-procs-not-working",         NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 7 this is broken for now */
13419 @@ -970,37 +969,37 @@
13420                                                 { "max-load-per-proc", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 8 */
13421                                                 { "idle-timeout",      NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 9 */
13422                                                 { "disable-time",      NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 10 */
13423 -                                               
13424 +
13425                                                 { "bin-environment",   NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },        /* 11 */
13426                                                 { "bin-copy-environment", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },     /* 12 */
13427 -                                               
13428 -                                               
13429 +
13430 +
13431                                                 { NULL,                NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
13432                                         };
13433 -                                       
13434 +
13435                                         if (da_host->type != TYPE_ARRAY) {
13436 -                                               log_error_write(srv, __FILE__, __LINE__, "ssSBS", 
13437 -                                                               "unexpected type for key:", 
13438 -                                                               "scgi.server", 
13439 +                                               log_error_write(srv, __FILE__, __LINE__, "ssSBS",
13440 +                                                               "unexpected type for key:",
13441 +                                                               "scgi.server",
13442                                                                 "[", da_host->key, "](string)");
13443 -                                               
13444 +
13445                                                 return HANDLER_ERROR;
13446                                         }
13447 -                                       
13448 +
13449                                         df = scgi_host_init();
13450 -                                       
13451 +
13452                                         df->check_local  = 1;
13453                                         df->min_procs    = 4;
13454                                         df->max_procs    = 4;
13455                                         df->max_load_per_proc = 1;
13456                                         df->idle_timeout = 60;
13457                                         df->disable_time = 60;
13458 -                                       
13459 +
13460                                         fcv[0].destination = df->host;
13461                                         fcv[1].destination = df->docroot;
13462                                         fcv[2].destination = df->unixsocket;
13463                                         fcv[3].destination = df->bin_path;
13464 -                                       
13465 +
13466                                         fcv[4].destination = &(df->check_local);
13467                                         fcv[5].destination = &(df->port);
13468                                         fcv[6].destination = &(df->min_procs);
13469 @@ -1008,47 +1007,47 @@
13470                                         fcv[8].destination = &(df->max_load_per_proc);
13471                                         fcv[9].destination = &(df->idle_timeout);
13472                                         fcv[10].destination = &(df->disable_time);
13473 -                                       
13474 +
13475                                         fcv[11].destination = df->bin_env;
13476                                         fcv[12].destination = df->bin_env_copy;
13477 -                                       
13478 -                                       
13479 +
13480 +
13481                                         if (0 != config_insert_values_internal(srv, da_host->value, fcv)) {
13482                                                 return HANDLER_ERROR;
13483                                         }
13484 -                                                       
13485 -                                       if ((!buffer_is_empty(df->host) || df->port) && 
13486 +
13487 +                                       if ((!buffer_is_empty(df->host) || df->port) &&
13488                                             !buffer_is_empty(df->unixsocket)) {
13489 -                                               log_error_write(srv, __FILE__, __LINE__, "s", 
13490 +                                               log_error_write(srv, __FILE__, __LINE__, "s",
13491                                                                 "either host+port or socket");
13492 -                                               
13493 +
13494                                                 return HANDLER_ERROR;
13495                                         }
13496 -                                       
13497 +
13498                                         if (!buffer_is_empty(df->unixsocket)) {
13499                                                 /* unix domain socket */
13500 -                                               
13501 +
13502                                                 if (df->unixsocket->used > UNIX_PATH_MAX - 2) {
13503 -                                                       log_error_write(srv, __FILE__, __LINE__, "s", 
13504 +                                                       log_error_write(srv, __FILE__, __LINE__, "s",
13505                                                                         "path of the unixdomain socket is too large");
13506                                                         return HANDLER_ERROR;
13507                                                 }
13508                                         } else {
13509                                                 /* tcp/ip */
13510 -                                               
13511 -                                               if (buffer_is_empty(df->host) && 
13512 +
13513 +                                               if (buffer_is_empty(df->host) &&
13514                                                     buffer_is_empty(df->bin_path)) {
13515 -                                                       log_error_write(srv, __FILE__, __LINE__, "sbbbs", 
13516 -                                                                       "missing key (string):", 
13517 +                                                       log_error_write(srv, __FILE__, __LINE__, "sbbbs",
13518 +                                                                       "missing key (string):",
13519                                                                         da->key,
13520                                                                         da_ext->key,
13521                                                                         da_host->key,
13522                                                                         "host");
13523 -                                                       
13524 +
13525                                                         return HANDLER_ERROR;
13526                                                 } else if (df->port == 0) {
13527 -                                                       log_error_write(srv, __FILE__, __LINE__, "sbbbs", 
13528 -                                                                       "missing key (short):", 
13529 +                                                       log_error_write(srv, __FILE__, __LINE__, "sbbbs",
13530 +                                                                       "missing key (short):",
13531                                                                         da->key,
13532                                                                         da_ext->key,
13533                                                                         da_host->key,
13534 @@ -1056,14 +1055,14 @@
13535                                                         return HANDLER_ERROR;
13536                                                 }
13537                                         }
13538 -                                               
13539 -                                       if (!buffer_is_empty(df->bin_path)) { 
13540 +
13541 +                                       if (!buffer_is_empty(df->bin_path)) {
13542                                                 /* a local socket + self spawning */
13543                                                 size_t pno;
13544 -                                               
13545 +
13546                                                 if (df->min_procs > df->max_procs) df->max_procs = df->min_procs;
13547                                                 if (df->max_load_per_proc < 1) df->max_load_per_proc = 0;
13548 -                                               
13549 +
13550                                                 if (s->debug) {
13551                                                         log_error_write(srv, __FILE__, __LINE__, "ssbsdsbsdsd",
13552                                                                         "--- scgi spawning local",
13553 @@ -1073,7 +1072,7 @@
13554                                                                         "\n\tmin-procs:", df->min_procs,
13555                                                                         "\n\tmax-procs:", df->max_procs);
13556                                                 }
13557 -                                               
13558 +
13559                                                 for (pno = 0; pno < df->min_procs; pno++) {
13560                                                         scgi_proc *proc;
13561  
13562 @@ -1088,7 +1087,7 @@
13563                                                                 buffer_append_string(proc->socket, "-");
13564                                                                 buffer_append_long(proc->socket, pno);
13565                                                         }
13566 -                                                       
13567 +
13568                                                         if (s->debug) {
13569                                                                 log_error_write(srv, __FILE__, __LINE__, "ssdsbsdsd",
13570                                                                                 "--- scgi spawning",
13571 @@ -1096,53 +1095,53 @@
13572                                                                                 "\n\tsocket", df->unixsocket,
13573                                                                                 "\n\tcurrent:", pno, "/", df->min_procs);
13574                                                         }
13575 -                                                       
13576 +
13577                                                         if (scgi_spawn_connection(srv, p, df, proc)) {
13578                                                                 log_error_write(srv, __FILE__, __LINE__, "s",
13579                                                                                 "[ERROR]: spawning fcgi failed.");
13580                                                                 return HANDLER_ERROR;
13581                                                         }
13582 -                                                       
13583 +
13584                                                         proc->next = df->first;
13585                                                         if (df->first)  df->first->prev = proc;
13586 -                                                       
13587 +
13588                                                         df->first = proc;
13589                                                 }
13590                                         } else {
13591                                                 scgi_proc *fp;
13592 -                                               
13593 +
13594                                                 fp = scgi_process_init();
13595                                                 fp->id = df->num_procs++;
13596                                                 df->max_id++;
13597                                                 df->active_procs++;
13598                                                 fp->state = PROC_STATE_RUNNING;
13599 -                                               
13600 +
13601                                                 if (buffer_is_empty(df->unixsocket)) {
13602                                                         fp->port = df->port;
13603                                                 } else {
13604                                                         buffer_copy_string_buffer(fp->socket, df->unixsocket);
13605                                                 }
13606 -                                               
13607 +
13608                                                 df->first = fp;
13609 -                                               
13610 +
13611                                                 df->min_procs = 1;
13612                                                 df->max_procs = 1;
13613                                         }
13614 -                                       
13615 +
13616                                         /* if extension already exists, take it */
13617                                         scgi_extension_insert(s->exts, da_ext->key, df);
13618                                 }
13619                         }
13620                 }
13621         }
13622 -       
13623 +
13624         return HANDLER_GO_ON;
13625  }
13626  
13627  static int scgi_set_state(server *srv, handler_ctx *hctx, scgi_connection_state_t state) {
13628         hctx->state = state;
13629         hctx->state_timestamp = srv->cur_ts;
13630 -       
13631 +
13632         return 0;
13633  }
13634  
13635 @@ -1150,34 +1149,34 @@
13636  void scgi_connection_cleanup(server *srv, handler_ctx *hctx) {
13637         plugin_data *p;
13638         connection  *con;
13639 -       
13640 +
13641         if (NULL == hctx) return;
13642 -       
13643 +
13644         p    = hctx->plugin_data;
13645         con  = hctx->remote_conn;
13646 -       
13647 +
13648         if (con->mode != p->id) {
13649                 WP();
13650                 return;
13651         }
13652 -       
13653 +
13654         if (hctx->fd != -1) {
13655                 fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
13656                 fdevent_unregister(srv->ev, hctx->fd);
13657                 close(hctx->fd);
13658                 srv->cur_fds--;
13659         }
13660 -       
13661 +
13662         if (hctx->host && hctx->proc) {
13663                 hctx->host->load--;
13664 -               
13665 +
13666                 if (hctx->got_proc) {
13667                         /* after the connect the process gets a load */
13668                         hctx->proc->load--;
13669 -                       
13670 +
13671                         if (p->conf.debug) {
13672                                 log_error_write(srv, __FILE__, __LINE__, "sddb",
13673 -                                               "release proc:", 
13674 +                                               "release proc:",
13675                                                 hctx->fd,
13676                                                 hctx->proc->pid, hctx->proc->socket);
13677                         }
13678 @@ -1186,87 +1185,87 @@
13679                 scgi_proclist_sort_down(srv, hctx->host, hctx->proc);
13680         }
13681  
13682 -       
13683 +
13684         handler_ctx_free(hctx);
13685 -       con->plugin_ctx[p->id] = NULL;  
13686 +       con->plugin_ctx[p->id] = NULL;
13687  }
13688  
13689  static int scgi_reconnect(server *srv, handler_ctx *hctx) {
13690         plugin_data *p    = hctx->plugin_data;
13691 -       
13692 -       /* child died 
13693 -        * 
13694 -        * 1. 
13695 -        * 
13696 +
13697 +       /* child died
13698 +        *
13699 +        * 1.
13700 +        *
13701          * connect was ok, connection was accepted
13702          * but the php accept loop checks after the accept if it should die or not.
13703 -        * 
13704 -        * if yes we can only detect it at a write() 
13705 -        * 
13706 +        *
13707 +        * if yes we can only detect it at a write()
13708 +        *
13709          * next step is resetting this attemp and setup a connection again
13710 -        * 
13711 +        *
13712          * if we have more then 5 reconnects for the same request, die
13713 -        * 
13714 -        * 2. 
13715 -        * 
13716 +        *
13717 +        * 2.
13718 +        *
13719          * we have a connection but the child died by some other reason
13720 -        * 
13721 +        *
13722          */
13723 -       
13724 +
13725         fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
13726         fdevent_unregister(srv->ev, hctx->fd);
13727         close(hctx->fd);
13728         srv->cur_fds--;
13729 -       
13730 +
13731         scgi_set_state(srv, hctx, FCGI_STATE_INIT);
13732 -       
13733 +
13734         hctx->request_id = 0;
13735         hctx->reconnects++;
13736 -       
13737 +
13738         if (p->conf.debug) {
13739                 log_error_write(srv, __FILE__, __LINE__, "sddb",
13740 -                               "release proc:", 
13741 +                               "release proc:",
13742                                 hctx->fd,
13743                                 hctx->proc->pid, hctx->proc->socket);
13744         }
13745 -       
13746 +
13747         hctx->proc->load--;
13748         scgi_proclist_sort_down(srv, hctx->host, hctx->proc);
13749 -       
13750 +
13751         return 0;
13752  }
13753  
13754  
13755  static handler_t scgi_connection_reset(server *srv, connection *con, void *p_d) {
13756         plugin_data *p = p_d;
13757 -       
13758 +
13759         scgi_connection_cleanup(srv, con->plugin_ctx[p->id]);
13760 -       
13761 +
13762         return HANDLER_GO_ON;
13763  }
13764  
13765  
13766  static int scgi_env_add(buffer *env, const char *key, size_t key_len, const char *val, size_t val_len) {
13767         size_t len;
13768 -       
13769 +
13770         if (!key || !val) return -1;
13771 -       
13772 +
13773         len = key_len + val_len + 2;
13774 -       
13775 +
13776         buffer_prepare_append(env, len);
13777  
13778 -       /* include the NUL */   
13779 +       /* include the NUL */
13780         memcpy(env->ptr + env->used, key, key_len + 1);
13781         env->used += key_len + 1;
13782         memcpy(env->ptr + env->used, val, val_len + 1);
13783         env->used += val_len + 1;
13784 -       
13785 +
13786         return 0;
13787  }
13788  
13789  
13790  /**
13791 - * 
13792 + *
13793   * returns
13794   *   -1 error
13795   *    0 connected
13796 @@ -1280,24 +1279,21 @@
13797         struct sockaddr_un scgi_addr_un;
13798  #endif
13799         socklen_t servlen;
13800 -       
13801 +
13802         scgi_extension_host *host = hctx->host;
13803         scgi_proc *proc   = hctx->proc;
13804         int scgi_fd       = hctx->fd;
13805 -       
13806 +
13807         memset(&scgi_addr, 0, sizeof(scgi_addr));
13808 -       
13809 +
13810         if (!buffer_is_empty(proc->socket)) {
13811  #ifdef HAVE_SYS_UN_H
13812                 /* use the unix domain socket */
13813                 scgi_addr_un.sun_family = AF_UNIX;
13814                 strcpy(scgi_addr_un.sun_path, proc->socket->ptr);
13815 -#ifdef SUN_LEN
13816 +               
13817                 servlen = SUN_LEN(&scgi_addr_un);
13818 -#else
13819 -               /* stevens says: */
13820 -               servlen = proc->socket->used + sizeof(scgi_addr_un.sun_family);
13821 -#endif
13822 +
13823                 scgi_addr = (struct sockaddr *) &scgi_addr_un;
13824  #else
13825                 return -1;
13826 @@ -1305,105 +1301,105 @@
13827         } else {
13828                 scgi_addr_in.sin_family = AF_INET;
13829                 if (0 == inet_aton(host->host->ptr, &(scgi_addr_in.sin_addr))) {
13830 -                       log_error_write(srv, __FILE__, __LINE__, "sbs", 
13831 -                                       "converting IP-adress failed for", host->host, 
13832 +                       log_error_write(srv, __FILE__, __LINE__, "sbs",
13833 +                                       "converting IP-adress failed for", host->host,
13834                                         "\nBe sure to specify an IP address here");
13835 -                       
13836 +
13837                         return -1;
13838                 }
13839                 scgi_addr_in.sin_port = htons(proc->port);
13840                 servlen = sizeof(scgi_addr_in);
13841 -               
13842 +
13843                 scgi_addr = (struct sockaddr *) &scgi_addr_in;
13844         }
13845 -       
13846 +
13847         if (-1 == connect(scgi_fd, scgi_addr, servlen)) {
13848 -               if (errno == EINPROGRESS || 
13849 +               if (errno == EINPROGRESS ||
13850                     errno == EALREADY ||
13851                     errno == EINTR) {
13852                         if (hctx->conf.debug) {
13853 -                               log_error_write(srv, __FILE__, __LINE__, "sd", 
13854 +                               log_error_write(srv, __FILE__, __LINE__, "sd",
13855                                                 "connect delayed, will continue later:", scgi_fd);
13856                         }
13857 -                       
13858 +
13859                         return 1;
13860                 } else {
13861 -                       log_error_write(srv, __FILE__, __LINE__, "sdsddb", 
13862 -                                       "connect failed:", scgi_fd, 
13863 +                       log_error_write(srv, __FILE__, __LINE__, "sdsddb",
13864 +                                       "connect failed:", scgi_fd,
13865                                         strerror(errno), errno,
13866                                         proc->port, proc->socket);
13867  
13868                         if (errno == EAGAIN) {
13869                                 /* this is Linux only */
13870 -                               
13871 -                               log_error_write(srv, __FILE__, __LINE__, "s", 
13872 +
13873 +                               log_error_write(srv, __FILE__, __LINE__, "s",
13874                                                 "If this happend on Linux: You have been run out of local ports. "
13875                                                 "Check the manual, section Performance how to handle this.");
13876 -                       } 
13877 -                       
13878 +                       }
13879 +
13880                         return -1;
13881                 }
13882         }
13883         if (hctx->conf.debug > 1) {
13884 -               log_error_write(srv, __FILE__, __LINE__, "sd", 
13885 +               log_error_write(srv, __FILE__, __LINE__, "sd",
13886                                 "connect succeeded: ", scgi_fd);
13887         }
13888  
13889  
13890 -       
13891 +
13892         return 0;
13893  }
13894  
13895  static int scgi_env_add_request_headers(server *srv, connection *con, plugin_data *p) {
13896         size_t i;
13897 -       
13898 +
13899         for (i = 0; i < con->request.headers->used; i++) {
13900                 data_string *ds;
13901 -               
13902 +
13903                 ds = (data_string *)con->request.headers->data[i];
13904 -               
13905 +
13906                 if (ds->value->used && ds->key->used) {
13907                         size_t j;
13908                         buffer_reset(srv->tmp_buf);
13909 -                       
13910 +
13911                         if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) {
13912                                 BUFFER_COPY_STRING_CONST(srv->tmp_buf, "HTTP_");
13913                                 srv->tmp_buf->used--;
13914                         }
13915 -                       
13916 +
13917                         buffer_prepare_append(srv->tmp_buf, ds->key->used + 2);
13918                         for (j = 0; j < ds->key->used - 1; j++) {
13919 -                               srv->tmp_buf->ptr[srv->tmp_buf->used++] = 
13920 -                                       light_isalpha(ds->key->ptr[j]) ? 
13921 +                               srv->tmp_buf->ptr[srv->tmp_buf->used++] =
13922 +                                       light_isalpha(ds->key->ptr[j]) ?
13923                                         ds->key->ptr[j] & ~32 : '_';
13924                         }
13925                         srv->tmp_buf->ptr[srv->tmp_buf->used++] = '\0';
13926 -                       
13927 +
13928                         scgi_env_add(p->scgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value));
13929                 }
13930         }
13931 -       
13932 +
13933         for (i = 0; i < con->environment->used; i++) {
13934                 data_string *ds;
13935 -               
13936 +
13937                 ds = (data_string *)con->environment->data[i];
13938 -               
13939 +
13940                 if (ds->value->used && ds->key->used) {
13941                         size_t j;
13942                         buffer_reset(srv->tmp_buf);
13943 -                       
13944 +
13945                         buffer_prepare_append(srv->tmp_buf, ds->key->used + 2);
13946                         for (j = 0; j < ds->key->used - 1; j++) {
13947 -                               srv->tmp_buf->ptr[srv->tmp_buf->used++] = 
13948 -                                       isalpha((unsigned char)ds->key->ptr[j]) ? 
13949 +                               srv->tmp_buf->ptr[srv->tmp_buf->used++] =
13950 +                                       isalpha((unsigned char)ds->key->ptr[j]) ?
13951                                         toupper((unsigned char)ds->key->ptr[j]) : '_';
13952                         }
13953                         srv->tmp_buf->ptr[srv->tmp_buf->used++] = '\0';
13954 -                       
13955 +
13956                         scgi_env_add(p->scgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value));
13957                 }
13958         }
13959 -       
13960 +
13961         return 0;
13962  }
13963  
13964 @@ -1415,20 +1411,20 @@
13965         char b2[INET6_ADDRSTRLEN + 1];
13966  #endif
13967         buffer *b;
13968 -       
13969 +
13970         plugin_data *p    = hctx->plugin_data;
13971         scgi_extension_host *host= hctx->host;
13972  
13973         connection *con   = hctx->remote_conn;
13974         server_socket *srv_sock = con->srv_socket;
13975 -       
13976 +
13977         sock_addr our_addr;
13978         socklen_t our_addr_len;
13979 -       
13980 +
13981         buffer_prepare_copy(p->scgi_env, 1024);
13982  
13983         /* CGI-SPEC 6.1.2, FastCGI spec 6.3 and SCGI spec */
13984 -               
13985 +
13986         /* request.content_length < SSIZE_MAX, see request.c */
13987         ltostr(buf, con->request.content_length);
13988         scgi_env_add(p->scgi_env, CONST_STR_LEN("CONTENT_LENGTH"), buf, strlen(buf));
13989 @@ -1436,13 +1432,13 @@
13990  
13991  
13992         scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_NAME"/"PACKAGE_VERSION));
13993 -       
13994 +
13995         if (con->server_name->used) {
13996                 scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_NAME"), CONST_BUF_LEN(con->server_name));
13997         } else {
13998  #ifdef HAVE_IPV6
13999 -               s = inet_ntop(srv_sock->addr.plain.sa_family, 
14000 -                             srv_sock->addr.plain.sa_family == AF_INET6 ? 
14001 +               s = inet_ntop(srv_sock->addr.plain.sa_family,
14002 +                             srv_sock->addr.plain.sa_family == AF_INET6 ?
14003                               (const void *) &(srv_sock->addr.ipv6.sin6_addr) :
14004                               (const void *) &(srv_sock->addr.ipv4.sin_addr),
14005                               b2, sizeof(b2)-1);
14006 @@ -1451,48 +1447,48 @@
14007  #endif
14008                 scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_NAME"), s, strlen(s));
14009         }
14010 -       
14011 +
14012         scgi_env_add(p->scgi_env, CONST_STR_LEN("GATEWAY_INTERFACE"), CONST_STR_LEN("CGI/1.1"));
14013 -       
14014 -       ltostr(buf, 
14015 +
14016 +       ltostr(buf,
14017  #ifdef HAVE_IPV6
14018                ntohs(srv_sock->addr.plain.sa_family ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port)
14019  #else
14020                ntohs(srv_sock->addr.ipv4.sin_port)
14021  #endif
14022                );
14023 -       
14024 +
14025         scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_PORT"), buf, strlen(buf));
14026 -       
14027 +
14028         /* get the server-side of the connection to the client */
14029         our_addr_len = sizeof(our_addr);
14030 -       
14031 +
14032         if (-1 == getsockname(con->fd, &(our_addr.plain), &our_addr_len)) {
14033                 s = inet_ntop_cache_get_ip(srv, &(srv_sock->addr));
14034         } else {
14035                 s = inet_ntop_cache_get_ip(srv, &(our_addr));
14036         }
14037         scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_ADDR"), s, strlen(s));
14038 -       
14039 -       ltostr(buf, 
14040 +
14041 +       ltostr(buf,
14042  #ifdef HAVE_IPV6
14043                ntohs(con->dst_addr.plain.sa_family ? con->dst_addr.ipv6.sin6_port : con->dst_addr.ipv4.sin_port)
14044  #else
14045                ntohs(con->dst_addr.ipv4.sin_port)
14046  #endif
14047                );
14048 -       
14049 +
14050         scgi_env_add(p->scgi_env, CONST_STR_LEN("REMOTE_PORT"), buf, strlen(buf));
14051 -       
14052 +
14053         s = inet_ntop_cache_get_ip(srv, &(con->dst_addr));
14054         scgi_env_add(p->scgi_env, CONST_STR_LEN("REMOTE_ADDR"), s, strlen(s));
14055 -       
14056 +
14057         if (!buffer_is_empty(con->authed_user)) {
14058                 scgi_env_add(p->scgi_env, CONST_STR_LEN("REMOTE_USER"),
14059                              CONST_BUF_LEN(con->authed_user));
14060         }
14061 -       
14062  
14063 +
14064         /*
14065          * SCRIPT_NAME, PATH_INFO and PATH_TRANSLATED according to
14066          * http://cgi-spec.golux.com/draft-coar-cgi-v11-03-clean.html
14067 @@ -1500,12 +1496,12 @@
14068          */
14069  
14070         scgi_env_add(p->scgi_env, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path));
14071 -               
14072 +
14073         if (!buffer_is_empty(con->request.pathinfo)) {
14074                 scgi_env_add(p->scgi_env, CONST_STR_LEN("PATH_INFO"), CONST_BUF_LEN(con->request.pathinfo));
14075 -               
14076 +
14077                 /* PATH_TRANSLATED is only defined if PATH_INFO is set */
14078 -               
14079 +
14080                 if (!buffer_is_empty(host->docroot)) {
14081                         buffer_copy_string_buffer(p->path, host->docroot);
14082                 } else {
14083 @@ -1526,19 +1522,19 @@
14084          */
14085  
14086         if (!buffer_is_empty(host->docroot)) {
14087 -               /* 
14088 -                * rewrite SCRIPT_FILENAME 
14089 -                * 
14090 +               /*
14091 +                * rewrite SCRIPT_FILENAME
14092 +                *
14093                  */
14094 -               
14095 +
14096                 buffer_copy_string_buffer(p->path, host->docroot);
14097                 buffer_append_string_buffer(p->path, con->uri.path);
14098 -               
14099 +
14100                 scgi_env_add(p->scgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path));
14101                 scgi_env_add(p->scgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(host->docroot));
14102         } else {
14103                 buffer_copy_string_buffer(p->path, con->physical.path);
14104 -               
14105 +
14106                 scgi_env_add(p->scgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path));
14107                 scgi_env_add(p->scgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(con->physical.doc_root));
14108         }
14109 @@ -1551,30 +1547,30 @@
14110         } else {
14111                 scgi_env_add(p->scgi_env, CONST_STR_LEN("QUERY_STRING"), CONST_STR_LEN(""));
14112         }
14113 -       
14114 +
14115         s = get_http_method_name(con->request.http_method);
14116         scgi_env_add(p->scgi_env, CONST_STR_LEN("REQUEST_METHOD"), s, strlen(s));
14117         scgi_env_add(p->scgi_env, CONST_STR_LEN("REDIRECT_STATUS"), CONST_STR_LEN("200")); /* if php is compiled with --force-redirect */
14118         s = get_http_version_name(con->request.http_version);
14119         scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_PROTOCOL"), s, strlen(s));
14120 -       
14121 +
14122  #ifdef USE_OPENSSL
14123         if (srv_sock->is_ssl) {
14124                 scgi_env_add(p->scgi_env, CONST_STR_LEN("HTTPS"), CONST_STR_LEN("on"));
14125         }
14126  #endif
14127 -       
14128 +
14129         scgi_env_add_request_headers(srv, con, p);
14130  
14131         b = chunkqueue_get_append_buffer(hctx->wb);
14132 -       
14133 +
14134         buffer_append_long(b, p->scgi_env->used);
14135         buffer_append_string_len(b, CONST_STR_LEN(":"));
14136         buffer_append_string_len(b, (const char *)p->scgi_env->ptr, p->scgi_env->used);
14137         buffer_append_string_len(b, CONST_STR_LEN(","));
14138  
14139         hctx->wb->bytes_in += b->used - 1;
14140 -       
14141 +
14142         if (con->request.content_length) {
14143                 chunkqueue *req_cq = con->request_content_queue;
14144                 chunk *req_c;
14145 @@ -1587,7 +1583,7 @@
14146  
14147                         /* we announce toWrite octects
14148                          * now take all the request_content chunk that we need to fill this request
14149 -                        * */   
14150 +                        * */
14151  
14152                         switch (req_c->type) {
14153                         case FILE_CHUNK:
14154 @@ -1615,32 +1611,32 @@
14155  
14156                                 req_c->offset += weHave;
14157                                 req_cq->bytes_out += weHave;
14158 -                               
14159 +
14160                                 hctx->wb->bytes_in += weHave;
14161  
14162                                 break;
14163                         default:
14164                                 break;
14165                         }
14166 -                       
14167 +
14168                         offset += weHave;
14169                 }
14170         }
14171 -       
14172 +
14173  #if 0
14174         for (i = 0; i < hctx->write_buffer->used; i++) {
14175                 fprintf(stderr, "%02x ", hctx->write_buffer->ptr[i]);
14176                 if ((i+1) % 16 == 0) {
14177                         size_t j;
14178                         for (j = i-15; j <= i; j++) {
14179 -                               fprintf(stderr, "%c", 
14180 +                               fprintf(stderr, "%c",
14181                                         isprint((unsigned char)hctx->write_buffer->ptr[j]) ? hctx->write_buffer->ptr[j] : '.');
14182                         }
14183                         fprintf(stderr, "\n");
14184                 }
14185         }
14186  #endif
14187 -       
14188 +
14189         return 0;
14190  }
14191  
14192 @@ -1648,32 +1644,32 @@
14193         char *ns;
14194         const char *s;
14195         int line = 0;
14196 -       
14197 +
14198         UNUSED(srv);
14199 -       
14200 +
14201         buffer_copy_string_buffer(p->parse_response, in);
14202 -       
14203 -       for (s = p->parse_response->ptr; 
14204 -            NULL != (ns = (eol == EOL_RN ? strstr(s, "\r\n") : strchr(s, '\n'))); 
14205 +
14206 +       for (s = p->parse_response->ptr;
14207 +            NULL != (ns = (eol == EOL_RN ? strstr(s, "\r\n") : strchr(s, '\n')));
14208              s = ns + (eol == EOL_RN ? 2 : 1), line++) {
14209                 const char *key, *value;
14210                 int key_len;
14211                 data_string *ds;
14212 -               
14213 +
14214                 ns[0] = '\0';
14215 -               
14216 -               if (line == 0 && 
14217 +
14218 +               if (line == 0 &&
14219                     0 == strncmp(s, "HTTP/1.", 7)) {
14220                         /* non-parsed header ... we parse them anyway */
14221 -                       
14222 +
14223                         if ((s[7] == '1' ||
14224                              s[7] == '0') &&
14225                             s[8] == ' ') {
14226                                 int status;
14227                                 /* after the space should be a status code for us */
14228 -                               
14229 +
14230                                 status = strtol(s+9, NULL, 10);
14231 -                               
14232 +
14233                                 if (con->http_status >= 100 &&
14234                                     con->http_status < 1000) {
14235                                         /* we expected 3 digits and didn't got them */
14236 @@ -1682,27 +1678,27 @@
14237                                 }
14238                         }
14239                 } else {
14240 -               
14241 +
14242                         key = s;
14243                         if (NULL == (value = strchr(s, ':'))) {
14244                                 /* we expect: "<key>: <value>\r\n" */
14245                                 continue;
14246                         }
14247 -                       
14248 +
14249                         key_len = value - key;
14250                         value += 1;
14251 -                       
14252 +
14253                         /* skip LWS */
14254                         while (*value == ' ' || *value == '\t') value++;
14255 -                       
14256 +
14257                         if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
14258                                 ds = data_response_init();
14259                         }
14260                         buffer_copy_string_len(ds->key, key, key_len);
14261                         buffer_copy_string(ds->value, value);
14262 -                       
14263 +
14264                         array_insert_unique(con->response.headers, (data_unset *)ds);
14265 -                       
14266 +
14267                         switch(key_len) {
14268                         case 4:
14269                                 if (0 == strncasecmp(key, "Date", key_len)) {
14270 @@ -1737,13 +1733,13 @@
14271                         }
14272                 }
14273         }
14274 -       
14275 +
14276         /* CGI/1.1 rev 03 - 7.2.1.2 */
14277         if ((con->parsed_response & HTTP_LOCATION) &&
14278             !(con->parsed_response & HTTP_STATUS)) {
14279                 con->http_status = 302;
14280         }
14281 -       
14282 +
14283         return 0;
14284  }
14285  
14286 @@ -1751,10 +1747,10 @@
14287  static int scgi_demux_response(server *srv, handler_ctx *hctx) {
14288         plugin_data *p    = hctx->plugin_data;
14289         connection  *con  = hctx->remote_conn;
14290 -       
14291 +
14292         while(1) {
14293                 int n;
14294 -               
14295 +
14296                 buffer_prepare_copy(hctx->response, 1024);
14297                 if (-1 == (n = read(hctx->fd, hctx->response->ptr, hctx->response->size - 1))) {
14298                         if (errno == EAGAIN || errno == EINTR) {
14299 @@ -1765,143 +1761,143 @@
14300                         log_error_write(srv, __FILE__, __LINE__, "sdd", strerror(errno), con->fd, hctx->fd);
14301                         return -1;
14302                 }
14303 -               
14304 +
14305                 if (n == 0) {
14306                         /* read finished */
14307 -                       
14308 +
14309                         con->file_finished = 1;
14310 -                       
14311 +
14312                         /* send final chunk */
14313                         http_chunk_append_mem(srv, con, NULL, 0);
14314                         joblist_append(srv, con);
14315 -                       
14316 +
14317                         return 1;
14318                 }
14319 -               
14320 +
14321                 hctx->response->ptr[n] = '\0';
14322                 hctx->response->used = n+1;
14323 -               
14324 +
14325                 /* split header from body */
14326 -               
14327 +
14328                 if (con->file_started == 0) {
14329                         char *c;
14330                         int in_header = 0;
14331                         int header_end = 0;
14332                         int cp, eol = EOL_UNSET;
14333                         size_t used = 0;
14334 -                       
14335 +
14336                         buffer_append_string_buffer(hctx->response_header, hctx->response);
14337 -                       
14338 +
14339                         /* nph (non-parsed headers) */
14340                         if (0 == strncmp(hctx->response_header->ptr, "HTTP/1.", 7)) in_header = 1;
14341 -                       
14342 +
14343                         /* search for the \r\n\r\n or \n\n in the string */
14344                         for (c = hctx->response_header->ptr, cp = 0, used = hctx->response_header->used - 1; used; c++, cp++, used--) {
14345                                 if (*c == ':') in_header = 1;
14346                                 else if (*c == '\n') {
14347                                         if (in_header == 0) {
14348                                                 /* got a response without a response header */
14349 -                                               
14350 +
14351                                                 c = NULL;
14352                                                 header_end = 1;
14353                                                 break;
14354                                         }
14355 -                                       
14356 +
14357                                         if (eol == EOL_UNSET) eol = EOL_N;
14358 -                                       
14359 +
14360                                         if (*(c+1) == '\n') {
14361                                                 header_end = 1;
14362                                                 break;
14363                                         }
14364 -                                       
14365 +
14366                                 } else if (used > 1 && *c == '\r' && *(c+1) == '\n') {
14367                                         if (in_header == 0) {
14368                                                 /* got a response without a response header */
14369 -                                               
14370 +
14371                                                 c = NULL;
14372                                                 header_end = 1;
14373                                                 break;
14374                                         }
14375 -                                       
14376 +
14377                                         if (eol == EOL_UNSET) eol = EOL_RN;
14378 -                                       
14379 +
14380                                         if (used > 3 &&
14381 -                                           *(c+2) == '\r' && 
14382 +                                           *(c+2) == '\r' &&
14383                                             *(c+3) == '\n') {
14384                                                 header_end = 1;
14385                                                 break;
14386                                         }
14387 -                                       
14388 +
14389                                         /* skip the \n */
14390                                         c++;
14391                                         cp++;
14392                                         used--;
14393                                 }
14394                         }
14395 -                       
14396 +
14397                         if (header_end) {
14398                                 if (c == NULL) {
14399                                         /* no header, but a body */
14400 -                                       
14401 +
14402                                         if (con->request.http_version == HTTP_VERSION_1_1) {
14403                                                 con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
14404                                         }
14405 -                                       
14406 +
14407                                         http_chunk_append_mem(srv, con, hctx->response_header->ptr, hctx->response_header->used);
14408                                         joblist_append(srv, con);
14409                                 } else {
14410                                         size_t hlen = c - hctx->response_header->ptr + (eol == EOL_RN ? 4 : 2);
14411                                         size_t blen = hctx->response_header->used - hlen - 1;
14412 -                               
14413 +
14414                                         /* a small hack: terminate after at the second \r */
14415                                         hctx->response_header->used = hlen + 1 - (eol == EOL_RN ? 2 : 1);
14416                                         hctx->response_header->ptr[hlen - (eol == EOL_RN ? 2 : 1)] = '\0';
14417 -                               
14418 +
14419                                         /* parse the response header */
14420                                         scgi_response_parse(srv, con, p, hctx->response_header, eol);
14421 -                                       
14422 +
14423                                         /* enable chunked-transfer-encoding */
14424                                         if (con->request.http_version == HTTP_VERSION_1_1 &&
14425                                             !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
14426                                                 con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
14427                                         }
14428 -                                       
14429 +
14430                                         if ((hctx->response->used != hlen) && blen > 0) {
14431                                                 http_chunk_append_mem(srv, con, c + (eol == EOL_RN ? 4: 2), blen + 1);
14432                                                 joblist_append(srv, con);
14433                                         }
14434                                 }
14435 -                               
14436 +
14437                                 con->file_started = 1;
14438                         }
14439                 } else {
14440                         http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used);
14441                         joblist_append(srv, con);
14442                 }
14443 -               
14444 -#if 0          
14445 +
14446 +#if 0
14447                 log_error_write(srv, __FILE__, __LINE__, "ddss", con->fd, hctx->fd, connection_get_state(con->state), b->ptr);
14448  #endif
14449         }
14450 -       
14451 +
14452         return 0;
14453  }
14454  
14455  
14456  int scgi_proclist_sort_up(server *srv, scgi_extension_host *host, scgi_proc *proc) {
14457         scgi_proc *p;
14458 -       
14459 +
14460         UNUSED(srv);
14461 -       
14462 -       /* we have been the smallest of the current list 
14463 -        * and we want to insert the node sorted as soon 
14464 +
14465 +       /* we have been the smallest of the current list
14466 +        * and we want to insert the node sorted as soon
14467          * possible
14468          *
14469 -        * 1 0 0 0 1 1 1 
14470 -        * |      ^ 
14471 +        * 1 0 0 0 1 1 1
14472 +        * |      ^
14473          * |      |
14474          * +------+
14475 -        * 
14476 +        *
14477          */
14478  
14479         /* nothing to sort, only one element */
14480 @@ -1909,9 +1905,9 @@
14481  
14482         for (p = proc; p->next && p->next->load < proc->load; p = p->next);
14483  
14484 -       /* no need to move something 
14485 +       /* no need to move something
14486          *
14487 -        * 1 2 2 2 3 3 3 
14488 +        * 1 2 2 2 3 3 3
14489          * ^
14490          * |
14491          * +
14492 @@ -1930,16 +1926,16 @@
14493  
14494         if (proc->prev) proc->prev->next = proc->next;
14495         if (proc->next) proc->next->prev = proc->prev;
14496 -       
14497 +
14498         /* proc should be right of p */
14499 -       
14500 +
14501         proc->next = p->next;
14502         proc->prev = p;
14503         if (p->next) p->next->prev = proc;
14504         p->next = proc;
14505  #if 0
14506         for(p = host->first; p; p = p->next) {
14507 -               log_error_write(srv, __FILE__, __LINE__, "dd", 
14508 +               log_error_write(srv, __FILE__, __LINE__, "dd",
14509                                 p->pid, p->load);
14510         }
14511  #else
14512 @@ -1951,21 +1947,21 @@
14513  
14514  int scgi_proclist_sort_down(server *srv, scgi_extension_host *host, scgi_proc *proc) {
14515         scgi_proc *p;
14516 -       
14517 +
14518         UNUSED(srv);
14519 -       
14520 -       /* we have been the smallest of the current list 
14521 -        * and we want to insert the node sorted as soon 
14522 +
14523 +       /* we have been the smallest of the current list
14524 +        * and we want to insert the node sorted as soon
14525          * possible
14526          *
14527 -        *  0 0 0 0 1 0 1 
14528 +        *  0 0 0 0 1 0 1
14529          * ^          |
14530          * |          |
14531          * +----------+
14532          *
14533          *
14534          * the basic is idea is:
14535 -        * - the last active scgi process should be still 
14536 +        * - the last active scgi process should be still
14537          *   in ram and is not swapped out yet
14538          * - processes that are not reused will be killed
14539          *   after some time by the trigger-handler
14540 @@ -1975,7 +1971,7 @@
14541          *   ice-cold processes are propably unused since more
14542          *   than 'unused-timeout', are swaped out and won't be
14543          *   reused in the next seconds anyway.
14544 -        * 
14545 +        *
14546          */
14547  
14548         /* nothing to sort, only one element */
14549 @@ -1984,16 +1980,16 @@
14550         for (p = host->first; p != proc && p->load < proc->load; p = p->next);
14551  
14552  
14553 -       /* no need to move something 
14554 +       /* no need to move something
14555          *
14556 -        * 1 2 2 2 3 3 3 
14557 +        * 1 2 2 2 3 3 3
14558          * ^
14559          * |
14560          * +
14561          *
14562          */
14563         if (p == proc) return 0;
14564 -       
14565 +
14566         /* we have to move left. If we are already the first element
14567          * we are done */
14568         if (host->first == proc) return 0;
14569 @@ -2009,9 +2005,9 @@
14570         p->prev = proc;
14571  
14572         if (proc->prev == NULL) host->first = proc;
14573 -#if 0  
14574 +#if 0
14575         for(p = host->first; p; p = p->next) {
14576 -               log_error_write(srv, __FILE__, __LINE__, "dd", 
14577 +               log_error_write(srv, __FILE__, __LINE__, "dd",
14578                                 p->pid, p->load);
14579         }
14580  #else
14581 @@ -2023,41 +2019,42 @@
14582  
14583  static int scgi_restart_dead_procs(server *srv, plugin_data *p, scgi_extension_host *host) {
14584         scgi_proc *proc;
14585 -       
14586 +
14587         for (proc = host->first; proc; proc = proc->next) {
14588                 if (p->conf.debug) {
14589 -                       log_error_write(srv, __FILE__, __LINE__,  "sbdbdddd", 
14590 -                                       "proc:", 
14591 -                                       host->host, proc->port, 
14592 +                       log_error_write(srv, __FILE__, __LINE__,  "sbdbdddd",
14593 +                                       "proc:",
14594 +                                       host->host, proc->port,
14595                                         proc->socket,
14596                                         proc->state,
14597                                         proc->is_local,
14598                                         proc->load,
14599                                         proc->pid);
14600                 }
14601 -               
14602 +
14603                 if (0 == proc->is_local) {
14604 -                       /* 
14605 -                        * external servers might get disabled 
14606 -                        * 
14607 -                        * enable the server again, perhaps it is back again 
14608 +                       /*
14609 +                        * external servers might get disabled
14610 +                        *
14611 +                        * enable the server again, perhaps it is back again
14612                          */
14613 -                       
14614 +
14615                         if ((proc->state == PROC_STATE_DISABLED) &&
14616                             (srv->cur_ts - proc->disable_ts > host->disable_time)) {
14617                                 proc->state = PROC_STATE_RUNNING;
14618                                 host->active_procs++;
14619 -                               
14620 -                               log_error_write(srv, __FILE__, __LINE__,  "sbdb", 
14621 -                                               "fcgi-server re-enabled:", 
14622 -                                               host->host, host->port, 
14623 +
14624 +                               log_error_write(srv, __FILE__, __LINE__,  "sbdb",
14625 +                                               "fcgi-server re-enabled:",
14626 +                                               host->host, host->port,
14627                                                 host->unixsocket);
14628                         }
14629                 } else {
14630                         /* the child should not terminate at all */
14631                         int status;
14632 -                       
14633 +
14634                         if (proc->state == PROC_STATE_DIED_WAIT_FOR_PID) {
14635 +#ifndef _WIN32
14636                                 switch(waitpid(proc->pid, &status, WNOHANG)) {
14637                                 case 0:
14638                                         /* child is still alive */
14639 @@ -2067,33 +2064,34 @@
14640                                 default:
14641                                         if (WIFEXITED(status)) {
14642  #if 0
14643 -                                               log_error_write(srv, __FILE__, __LINE__, "sdsd", 
14644 +                                               log_error_write(srv, __FILE__, __LINE__, "sdsd",
14645                                                                 "child exited, pid:", proc->pid,
14646                                                                 "status:", WEXITSTATUS(status));
14647  #endif
14648                                         } else if (WIFSIGNALED(status)) {
14649 -                                               log_error_write(srv, __FILE__, __LINE__, "sd", 
14650 -                                                               "child signaled:", 
14651 +                                               log_error_write(srv, __FILE__, __LINE__, "sd",
14652 +                                                               "child signaled:",
14653                                                                 WTERMSIG(status));
14654                                         } else {
14655 -                                               log_error_write(srv, __FILE__, __LINE__, "sd", 
14656 -                                                               "child died somehow:", 
14657 +                                               log_error_write(srv, __FILE__, __LINE__, "sd",
14658 +                                                               "child died somehow:",
14659                                                                 status);
14660                                         }
14661 -                                       
14662 +
14663                                         proc->state = PROC_STATE_DIED;
14664                                         break;
14665                                 }
14666 +#endif
14667                         }
14668 -                       
14669 -                       /* 
14670 +
14671 +                       /*
14672                          * local servers might died, but we restart them
14673 -                        * 
14674 +                        *
14675                          */
14676                         if (proc->state == PROC_STATE_DIED &&
14677                             proc->load == 0) {
14678                                 /* restart the child */
14679 -                               
14680 +
14681                                 if (p->conf.debug) {
14682                                         log_error_write(srv, __FILE__, __LINE__, "ssdsbsdsd",
14683                                                         "--- scgi spawning",
14684 @@ -2101,18 +2099,18 @@
14685                                                         "\n\tsocket", host->unixsocket,
14686                                                         "\n\tcurrent:", 1, "/", host->min_procs);
14687                                 }
14688 -                               
14689 +
14690                                 if (scgi_spawn_connection(srv, p, host, proc)) {
14691                                         log_error_write(srv, __FILE__, __LINE__, "s",
14692                                                         "ERROR: spawning fcgi failed.");
14693                                         return HANDLER_ERROR;
14694                                 }
14695 -                               
14696 +
14697                                 scgi_proclist_sort_down(srv, host, proc);
14698                         }
14699                 }
14700         }
14701 -       
14702 +
14703         return 0;
14704  }
14705  
14706 @@ -2121,13 +2119,13 @@
14707         plugin_data *p    = hctx->plugin_data;
14708         scgi_extension_host *host= hctx->host;
14709         connection *con   = hctx->remote_conn;
14710 -       
14711 +
14712         int ret;
14713  
14714 -       /* sanity check */      
14715 +       /* sanity check */
14716         if (!host ||
14717             ((!host->host->used || !host->port) && !host->unixsocket->used)) {
14718 -               log_error_write(srv, __FILE__, __LINE__, "sxddd", 
14719 +               log_error_write(srv, __FILE__, __LINE__, "sxddd",
14720                                 "write-req: error",
14721                                 host,
14722                                 host->host->used,
14723 @@ -2135,179 +2133,180 @@
14724                                 host->unixsocket->used);
14725                 return HANDLER_ERROR;
14726         }
14727 -       
14728  
14729 +
14730         switch(hctx->state) {
14731         case FCGI_STATE_INIT:
14732                 ret = host->unixsocket->used ? AF_UNIX : AF_INET;
14733 -               
14734 +
14735                 if (-1 == (hctx->fd = socket(ret, SOCK_STREAM, 0))) {
14736                         if (errno == EMFILE ||
14737                             errno == EINTR) {
14738 -                               log_error_write(srv, __FILE__, __LINE__, "sd", 
14739 +                               log_error_write(srv, __FILE__, __LINE__, "sd",
14740                                                 "wait for fd at connection:", con->fd);
14741 -                               
14742 +
14743                                 return HANDLER_WAIT_FOR_FD;
14744                         }
14745 -                       
14746 -                       log_error_write(srv, __FILE__, __LINE__, "ssdd", 
14747 +
14748 +                       log_error_write(srv, __FILE__, __LINE__, "ssdd",
14749                                         "socket failed:", strerror(errno), srv->cur_fds, srv->max_fds);
14750                         return HANDLER_ERROR;
14751                 }
14752                 hctx->fde_ndx = -1;
14753 -               
14754 +
14755                 srv->cur_fds++;
14756 -               
14757 +
14758                 fdevent_register(srv->ev, hctx->fd, scgi_handle_fdevent, hctx);
14759 -               
14760 +
14761                 if (-1 == fdevent_fcntl_set(srv->ev, hctx->fd)) {
14762 -                       log_error_write(srv, __FILE__, __LINE__, "ss", 
14763 +                       log_error_write(srv, __FILE__, __LINE__, "ss",
14764                                         "fcntl failed: ", strerror(errno));
14765 -                       
14766 +
14767                         return HANDLER_ERROR;
14768                 }
14769 -               
14770 +
14771                 /* fall through */
14772         case FCGI_STATE_CONNECT:
14773                 if (hctx->state == FCGI_STATE_INIT) {
14774 -                       for (hctx->proc = hctx->host->first; 
14775 -                            hctx->proc && hctx->proc->state != PROC_STATE_RUNNING; 
14776 +                       for (hctx->proc = hctx->host->first;
14777 +                            hctx->proc && hctx->proc->state != PROC_STATE_RUNNING;
14778                              hctx->proc = hctx->proc->next);
14779 -                       
14780 +
14781                         /* all childs are dead */
14782                         if (hctx->proc == NULL) {
14783                                 hctx->fde_ndx = -1;
14784 -                               
14785 +
14786                                 return HANDLER_ERROR;
14787                         }
14788 -                       
14789 +
14790                         if (hctx->proc->is_local) {
14791                                 hctx->pid = hctx->proc->pid;
14792                         }
14793 -                       
14794 +
14795                         switch (scgi_establish_connection(srv, hctx)) {
14796                         case 1:
14797                                 scgi_set_state(srv, hctx, FCGI_STATE_CONNECT);
14798 -                               
14799 +
14800                                 /* connection is in progress, wait for an event and call getsockopt() below */
14801 -                               
14802 +
14803                                 fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
14804 -                               
14805 +
14806                                 return HANDLER_WAIT_FOR_EVENT;
14807                         case -1:
14808                                 /* if ECONNREFUSED choose another connection -> FIXME */
14809                                 hctx->fde_ndx = -1;
14810 -                               
14811 +
14812                                 return HANDLER_ERROR;
14813                         default:
14814                                 /* everything is ok, go on */
14815                                 break;
14816                         }
14817  
14818 -                       
14819 +
14820                 } else {
14821                         int socket_error;
14822                         socklen_t socket_error_len = sizeof(socket_error);
14823 -                       
14824 +
14825                         /* try to finish the connect() */
14826                         if (0 != getsockopt(hctx->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) {
14827 -                               log_error_write(srv, __FILE__, __LINE__, "ss", 
14828 +                               log_error_write(srv, __FILE__, __LINE__, "ss",
14829                                                 "getsockopt failed:", strerror(errno));
14830 -                               
14831 +
14832                                 return HANDLER_ERROR;
14833                         }
14834                         if (socket_error != 0) {
14835                                 if (!hctx->proc->is_local || p->conf.debug) {
14836                                         /* local procs get restarted */
14837 -                                       
14838 +
14839                                         log_error_write(srv, __FILE__, __LINE__, "ss",
14840 -                                                       "establishing connection failed:", strerror(socket_error), 
14841 +                                                       "establishing connection failed:", strerror(socket_error),
14842                                                         "port:", hctx->proc->port);
14843                                 }
14844 -                               
14845 +
14846                                 return HANDLER_ERROR;
14847                         }
14848                 }
14849 -               
14850 +
14851                 /* ok, we have the connection */
14852 -               
14853 +
14854                 hctx->proc->load++;
14855                 hctx->proc->last_used = srv->cur_ts;
14856                 hctx->got_proc = 1;
14857 -               
14858 +
14859                 if (p->conf.debug) {
14860                         log_error_write(srv, __FILE__, __LINE__, "sddbdd",
14861 -                                       "got proc:", 
14862 +                                       "got proc:",
14863                                         hctx->fd,
14864 -                                       hctx->proc->pid, 
14865 -                                       hctx->proc->socket, 
14866 +                                       hctx->proc->pid,
14867 +                                       hctx->proc->socket,
14868                                         hctx->proc->port,
14869                                         hctx->proc->load);
14870                 }
14871  
14872                 /* move the proc-list entry down the list */
14873                 scgi_proclist_sort_up(srv, hctx->host, hctx->proc);
14874 -               
14875 +
14876                 scgi_set_state(srv, hctx, FCGI_STATE_PREPARE_WRITE);
14877                 /* fall through */
14878         case FCGI_STATE_PREPARE_WRITE:
14879                 scgi_create_env(srv, hctx);
14880 -               
14881 +
14882                 scgi_set_state(srv, hctx, FCGI_STATE_WRITE);
14883 -               
14884 +
14885                 /* fall through */
14886         case FCGI_STATE_WRITE:
14887 -               ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb); 
14888 +               ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb);
14889  
14890                 chunkqueue_remove_finished_chunks(hctx->wb);
14891 -       
14892 +
14893                 if (-1 == ret) {
14894                         if (errno == ENOTCONN) {
14895 -                               /* the connection got dropped after accept() 
14896 -                                * 
14897 -                                * this is most of the time a PHP which dies 
14898 +                               /* the connection got dropped after accept()
14899 +                                *
14900 +                                * this is most of the time a PHP which dies
14901                                  * after PHP_FCGI_MAX_REQUESTS
14902 -                                * 
14903 -                                */ 
14904 +                                *
14905 +                                */
14906                                 if (hctx->wb->bytes_out == 0 &&
14907                                     hctx->reconnects < 5) {
14908 -                                       usleep(10000); /* take away the load of the webserver 
14909 -                                                       * to let the php a chance to restart 
14910 +#ifndef _WIN32
14911 +                                       usleep(10000); /* take away the load of the webserver
14912 +                                                       * to let the php a chance to restart
14913                                                         */
14914 -                                       
14915 +#endif
14916                                         scgi_reconnect(srv, hctx);
14917 -                               
14918 +
14919                                         return HANDLER_WAIT_FOR_FD;
14920                                 }
14921 -                               
14922 +
14923                                 /* not reconnected ... why
14924 -                                * 
14925 +                                *
14926                                  * far@#lighttpd report this for FreeBSD
14927 -                                * 
14928 +                                *
14929                                  */
14930 -                               
14931 -                               log_error_write(srv, __FILE__, __LINE__, "ssdsd", 
14932 +
14933 +                               log_error_write(srv, __FILE__, __LINE__, "ssosd",
14934                                                 "[REPORT ME] connection was dropped after accept(). reconnect() denied:",
14935                                                 "write-offset:", hctx->wb->bytes_out,
14936                                                 "reconnect attempts:", hctx->reconnects);
14937 -                               
14938 +
14939                                 return HANDLER_ERROR;
14940                         }
14941 -                       
14942 +
14943                         if ((errno != EAGAIN) &&
14944                             (errno != EINTR)) {
14945 -                               
14946 -                               log_error_write(srv, __FILE__, __LINE__, "ssd", 
14947 +
14948 +                               log_error_write(srv, __FILE__, __LINE__, "ssd",
14949                                                 "write failed:", strerror(errno), errno);
14950 -                               
14951 +
14952                                 return HANDLER_ERROR;
14953                         } else {
14954                                 fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
14955 -                               
14956 +
14957                                 return HANDLER_WAIT_FOR_EVENT;
14958                         }
14959                 }
14960 -               
14961 +
14962                 if (hctx->wb->bytes_out == hctx->wb->bytes_in) {
14963                         /* we don't need the out event anymore */
14964                         fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
14965 @@ -2315,10 +2314,10 @@
14966                         scgi_set_state(srv, hctx, FCGI_STATE_READ);
14967                 } else {
14968                         fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
14969 -                       
14970 +
14971                         return HANDLER_WAIT_FOR_EVENT;
14972                 }
14973 -               
14974 +
14975                 break;
14976         case FCGI_STATE_READ:
14977                 /* waiting for a response */
14978 @@ -2327,67 +2326,67 @@
14979                 log_error_write(srv, __FILE__, __LINE__, "s", "(debug) unknown state");
14980                 return HANDLER_ERROR;
14981         }
14982 -       
14983 +
14984         return HANDLER_WAIT_FOR_EVENT;
14985  }
14986  
14987  SUBREQUEST_FUNC(mod_scgi_handle_subrequest) {
14988         plugin_data *p = p_d;
14989 -       
14990 +
14991         handler_ctx *hctx = con->plugin_ctx[p->id];
14992         scgi_proc *proc;
14993         scgi_extension_host *host;
14994 -       
14995 +
14996         if (NULL == hctx) return HANDLER_GO_ON;
14997 -       
14998 +
14999         /* not my job */
15000         if (con->mode != p->id) return HANDLER_GO_ON;
15001 -       
15002 +
15003         /* ok, create the request */
15004         switch(scgi_write_request(srv, hctx)) {
15005         case HANDLER_ERROR:
15006                 proc = hctx->proc;
15007                 host = hctx->host;
15008 -               
15009 -               if (proc && 
15010 +
15011 +               if (proc &&
15012                     0 == proc->is_local &&
15013                     proc->state != PROC_STATE_DISABLED) {
15014                         /* only disable remote servers as we don't manage them*/
15015 -                       
15016 -                       log_error_write(srv, __FILE__, __LINE__,  "sbdb", "fcgi-server disabled:", 
15017 +
15018 +                       log_error_write(srv, __FILE__, __LINE__,  "sbdb", "fcgi-server disabled:",
15019                                         host->host,
15020                                         proc->port,
15021                                         proc->socket);
15022 -                       
15023 +
15024                         /* disable this server */
15025                         proc->disable_ts = srv->cur_ts;
15026                         proc->state = PROC_STATE_DISABLED;
15027                         host->active_procs--;
15028                 }
15029 -               
15030 +
15031                 if (hctx->state == FCGI_STATE_INIT ||
15032                     hctx->state == FCGI_STATE_CONNECT) {
15033 -                       /* connect() or getsockopt() failed, 
15034 -                        * restart the request-handling 
15035 +                       /* connect() or getsockopt() failed,
15036 +                        * restart the request-handling
15037                          */
15038                         if (proc && proc->is_local) {
15039  
15040                                 if (p->conf.debug) {
15041 -                                       log_error_write(srv, __FILE__, __LINE__,  "sbdb", "connect() to scgi failed, restarting the request-handling:", 
15042 +                                       log_error_write(srv, __FILE__, __LINE__,  "sbdb", "connect() to scgi failed, restarting the request-handling:",
15043                                                         host->host,
15044                                                         proc->port,
15045                                                         proc->socket);
15046                                 }
15047  
15048 -                               /* 
15049 +                               /*
15050                                  * several hctx might reference the same proc
15051 -                                * 
15052 +                                *
15053                                  * Only one of them should mark the proc as dead all the other
15054                                  * ones should just take a new one.
15055 -                                * 
15056 +                                *
15057                                  * If a new proc was started with the old struct this might lead
15058                                  * the mark a perfect proc as dead otherwise
15059 -                                * 
15060 +                                *
15061                                  */
15062                                 if (proc->state == PROC_STATE_RUNNING &&
15063                                     hctx->pid == proc->pid) {
15064 @@ -2395,25 +2394,25 @@
15065                                 }
15066                         }
15067                         scgi_restart_dead_procs(srv, p, host);
15068 -                       
15069 +
15070                         scgi_connection_cleanup(srv, hctx);
15071 -                       
15072 +
15073                         buffer_reset(con->physical.path);
15074                         con->mode = DIRECT;
15075                         joblist_append(srv, con);
15076 -                       
15077 -                       /* mis-using HANDLER_WAIT_FOR_FD to break out of the loop 
15078 -                        * and hope that the childs will be restarted 
15079 -                        * 
15080 +
15081 +                       /* mis-using HANDLER_WAIT_FOR_FD to break out of the loop
15082 +                        * and hope that the childs will be restarted
15083 +                        *
15084                          */
15085                         return HANDLER_WAIT_FOR_FD;
15086                 } else {
15087                         scgi_connection_cleanup(srv, hctx);
15088 -                       
15089 +
15090                         buffer_reset(con->physical.path);
15091                         con->mode = DIRECT;
15092                         con->http_status = 503;
15093 -                       
15094 +
15095                         return HANDLER_FINISHED;
15096                 }
15097         case HANDLER_WAIT_FOR_EVENT:
15098 @@ -2433,23 +2432,23 @@
15099  static handler_t scgi_connection_close(server *srv, handler_ctx *hctx) {
15100         plugin_data *p;
15101         connection  *con;
15102 -       
15103 +
15104         if (NULL == hctx) return HANDLER_GO_ON;
15105 -       
15106 +
15107         p    = hctx->plugin_data;
15108         con  = hctx->remote_conn;
15109 -       
15110 +
15111         if (con->mode != p->id) return HANDLER_GO_ON;
15112 -       
15113 -       log_error_write(srv, __FILE__, __LINE__, "ssdsd", 
15114 -                       "emergency exit: scgi:", 
15115 +
15116 +       log_error_write(srv, __FILE__, __LINE__, "ssdsd",
15117 +                       "emergency exit: scgi:",
15118                         "connection-fd:", con->fd,
15119                         "fcgi-fd:", hctx->fd);
15120 -       
15121 -       
15122 -       
15123 +
15124 +
15125 +
15126         scgi_connection_cleanup(srv, hctx);
15127 -       
15128 +
15129         return HANDLER_FINISHED;
15130  }
15131  
15132 @@ -2459,7 +2458,7 @@
15133         handler_ctx *hctx = ctx;
15134         connection  *con  = hctx->remote_conn;
15135         plugin_data *p    = hctx->plugin_data;
15136 -       
15137 +
15138         scgi_proc *proc   = hctx->proc;
15139         scgi_extension_host *host= hctx->host;
15140  
15141 @@ -2471,15 +2470,15 @@
15142                 case 1:
15143                         /* we are done */
15144                         scgi_connection_cleanup(srv, hctx);
15145 -                       
15146 +
15147                         joblist_append(srv, con);
15148                         return HANDLER_FINISHED;
15149                 case -1:
15150                         if (proc->pid && proc->state != PROC_STATE_DIED) {
15151                                 int status;
15152 -                               
15153 +
15154                                 /* only fetch the zombie if it is not already done */
15155 -                               
15156 +#ifndef _WIN32
15157                                 switch(waitpid(proc->pid, &status, WNOHANG)) {
15158                                 case 0:
15159                                         /* child is still alive */
15160 @@ -2489,19 +2488,19 @@
15161                                 default:
15162                                         /* the child should not terminate at all */
15163                                         if (WIFEXITED(status)) {
15164 -                                               log_error_write(srv, __FILE__, __LINE__, "sdsd", 
15165 +                                               log_error_write(srv, __FILE__, __LINE__, "sdsd",
15166                                                                 "child exited, pid:", proc->pid,
15167                                                                 "status:", WEXITSTATUS(status));
15168                                         } else if (WIFSIGNALED(status)) {
15169 -                                               log_error_write(srv, __FILE__, __LINE__, "sd", 
15170 -                                                               "child signaled:", 
15171 +                                               log_error_write(srv, __FILE__, __LINE__, "sd",
15172 +                                                               "child signaled:",
15173                                                                 WTERMSIG(status));
15174                                         } else {
15175 -                                               log_error_write(srv, __FILE__, __LINE__, "sd", 
15176 -                                                               "child died somehow:", 
15177 +                                               log_error_write(srv, __FILE__, __LINE__, "sd",
15178 +                                                               "child died somehow:",
15179                                                                 status);
15180                                         }
15181 -                                       
15182 +
15183                                         if (p->conf.debug) {
15184                                                 log_error_write(srv, __FILE__, __LINE__, "ssdsbsdsd",
15185                                                                 "--- scgi spawning",
15186 @@ -2509,40 +2508,41 @@
15187                                                                 "\n\tsocket", host->unixsocket,
15188                                                                 "\n\tcurrent:", 1, "/", host->min_procs);
15189                                         }
15190 -                                       
15191 +
15192                                         if (scgi_spawn_connection(srv, p, host, proc)) {
15193                                                 /* child died */
15194                                                 proc->state = PROC_STATE_DIED;
15195                                         } else {
15196                                                 scgi_proclist_sort_down(srv, host, proc);
15197                                         }
15198 -                                       
15199 +
15200                                         break;
15201                                 }
15202 +#endif
15203                         }
15204  
15205                         if (con->file_started == 0) {
15206                                 /* nothing has been send out yet, try to use another child */
15207 -                               
15208 +
15209                                 if (hctx->wb->bytes_out == 0 &&
15210                                     hctx->reconnects < 5) {
15211                                         scgi_reconnect(srv, hctx);
15212 -                                       
15213 -                                       log_error_write(srv, __FILE__, __LINE__, "sdsdsd", 
15214 +
15215 +                                       log_error_write(srv, __FILE__, __LINE__, "sdsdsd",
15216                                                 "response not sent, request not sent, reconnection.",
15217                                                 "connection-fd:", con->fd,
15218                                                 "fcgi-fd:", hctx->fd);
15219 -                                       
15220 +
15221                                         return HANDLER_WAIT_FOR_FD;
15222                                 }
15223 -                               
15224 -                               log_error_write(srv, __FILE__, __LINE__, "sdsdsd", 
15225 +
15226 +                               log_error_write(srv, __FILE__, __LINE__, "sosdsd",
15227                                                 "response not sent, request sent:", hctx->wb->bytes_out,
15228                                                 "connection-fd:", con->fd,
15229                                                 "fcgi-fd:", hctx->fd);
15230 -                               
15231 +
15232                                 scgi_connection_cleanup(srv, hctx);
15233 -                               
15234 +
15235                                 connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
15236                                 buffer_reset(con->physical.path);
15237                                 con->http_status = 500;
15238 @@ -2550,76 +2550,76 @@
15239                         } else {
15240                                 /* response might have been already started, kill the connection */
15241                                 scgi_connection_cleanup(srv, hctx);
15242 -                               
15243 -                               log_error_write(srv, __FILE__, __LINE__, "ssdsd", 
15244 +
15245 +                               log_error_write(srv, __FILE__, __LINE__, "ssdsd",
15246                                                 "response already sent out, termination connection",
15247                                                 "connection-fd:", con->fd,
15248                                                 "fcgi-fd:", hctx->fd);
15249 -                               
15250 +
15251                                 connection_set_state(srv, con, CON_STATE_ERROR);
15252                         }
15253  
15254                         /* */
15255 -                       
15256 -                       
15257 +
15258 +
15259                         joblist_append(srv, con);
15260                         return HANDLER_FINISHED;
15261                 }
15262         }
15263 -       
15264 +
15265         if (revents & FDEVENT_OUT) {
15266                 if (hctx->state == FCGI_STATE_CONNECT ||
15267                     hctx->state == FCGI_STATE_WRITE) {
15268                         /* we are allowed to send something out
15269 -                        * 
15270 +                        *
15271                          * 1. in a unfinished connect() call
15272                          * 2. in a unfinished write() call (long POST request)
15273                          */
15274                         return mod_scgi_handle_subrequest(srv, con, p);
15275                 } else {
15276 -                       log_error_write(srv, __FILE__, __LINE__, "sd", 
15277 -                                       "got a FDEVENT_OUT and didn't know why:", 
15278 +                       log_error_write(srv, __FILE__, __LINE__, "sd",
15279 +                                       "got a FDEVENT_OUT and didn't know why:",
15280                                         hctx->state);
15281                 }
15282         }
15283 -       
15284 +
15285         /* perhaps this issue is already handled */
15286         if (revents & FDEVENT_HUP) {
15287                 if (hctx->state == FCGI_STATE_CONNECT) {
15288                         /* getoptsock will catch this one (right ?)
15289 -                        * 
15290 -                        * if we are in connect we might get a EINPROGRESS 
15291 -                        * in the first call and a FDEVENT_HUP in the 
15292 +                        *
15293 +                        * if we are in connect we might get a EINPROGRESS
15294 +                        * in the first call and a FDEVENT_HUP in the
15295                          * second round
15296 -                        * 
15297 +                        *
15298                          * FIXME: as it is a bit ugly.
15299 -                        * 
15300 +                        *
15301                          */
15302                         return mod_scgi_handle_subrequest(srv, con, p);
15303                 } else if (hctx->state == FCGI_STATE_READ &&
15304                            hctx->proc->port == 0) {
15305                         /* FIXME:
15306 -                        * 
15307 +                        *
15308                          * ioctl says 8192 bytes to read from PHP and we receive directly a HUP for the socket
15309                          * even if the FCGI_FIN packet is not received yet
15310                          */
15311                 } else {
15312 -                       log_error_write(srv, __FILE__, __LINE__, "sbSBSDSd", 
15313 -                                       "error: unexpected close of scgi connection for", 
15314 +                       log_error_write(srv, __FILE__, __LINE__, "sbSBSDSd",
15315 +                                       "error: unexpected close of scgi connection for",
15316                                         con->uri.path,
15317 -                                       "(no scgi process on host: ", 
15318 +                                       "(no scgi process on host: ",
15319                                         host->host,
15320 -                                       ", port: ", 
15321 +                                       ", port: ",
15322                                         host->port,
15323                                         " ?)",
15324                                         hctx->state);
15325 -                       
15326 +
15327                         connection_set_state(srv, con, CON_STATE_ERROR);
15328                         scgi_connection_close(srv, hctx);
15329                         joblist_append(srv, con);
15330                 }
15331         } else if (revents & FDEVENT_ERR) {
15332 -               log_error_write(srv, __FILE__, __LINE__, "s", 
15333 +               log_error_write(srv, __FILE__, __LINE__, "s",
15334                                 "fcgi: got a FDEVENT_ERR. Don't know why.");
15335                 /* kill all connections to the scgi process */
15336  
15337 @@ -2628,43 +2628,40 @@
15338                 scgi_connection_close(srv, hctx);
15339                 joblist_append(srv, con);
15340         }
15341 -       
15342 +
15343         return HANDLER_FINISHED;
15344  }
15345 -#define PATCH(x) \
15346 -       p->conf.x = s->x;
15347 +
15348  static int scgi_patch_connection(server *srv, connection *con, plugin_data *p) {
15349         size_t i, j;
15350         plugin_config *s = p->config_storage[0];
15351 -       
15352 -       PATCH(exts);
15353 -       PATCH(debug);
15354 -       
15355 +
15356 +       PATCH_OPTION(exts);
15357 +       PATCH_OPTION(debug);
15358 +
15359         /* skip the first, the global context */
15360         for (i = 1; i < srv->config_context->used; i++) {
15361                 data_config *dc = (data_config *)srv->config_context->data[i];
15362                 s = p->config_storage[i];
15363 -               
15364 +
15365                 /* condition didn't match */
15366                 if (!config_check_cond(srv, con, dc)) continue;
15367 -               
15368 +
15369                 /* merge config */
15370                 for (j = 0; j < dc->value->used; j++) {
15371                         data_unset *du = dc->value->data[j];
15372 -                       
15373 +
15374                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("scgi.server"))) {
15375 -                               PATCH(exts);
15376 +                               PATCH_OPTION(exts);
15377                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("scgi.debug"))) {
15378 -                               PATCH(debug);
15379 +                               PATCH_OPTION(debug);
15380                         }
15381                 }
15382         }
15383 -       
15384 +
15385         return 0;
15386  }
15387 -#undef PATCH
15388  
15389 -
15390  static handler_t scgi_check_extension(server *srv, connection *con, void *p_d, int uri_path_handler) {
15391         plugin_data *p = p_d;
15392         size_t s_len;
15393 @@ -2673,30 +2670,30 @@
15394         size_t k;
15395         buffer *fn;
15396         scgi_extension *extension = NULL;
15397 -       
15398 +
15399         /* Possibly, we processed already this request */
15400         if (con->file_started == 1) return HANDLER_GO_ON;
15401 -       
15402 +
15403         fn = uri_path_handler ? con->uri.path : con->physical.path;
15404  
15405         if (buffer_is_empty(fn)) return HANDLER_GO_ON;
15406  
15407         s_len = fn->used - 1;
15408 -       
15409 +
15410         scgi_patch_connection(srv, con, p);
15411  
15412         /* check if extension matches */
15413         for (k = 0; k < p->conf.exts->used; k++) {
15414                 size_t ct_len;
15415 -               
15416 +
15417                 extension = p->conf.exts->exts[k];
15418 -               
15419 +
15420                 if (extension->key->used == 0) continue;
15421 -               
15422 +
15423                 ct_len = extension->key->used - 1;
15424 -               
15425 +
15426                 if (s_len < ct_len) continue;
15427 -               
15428 +
15429                 /* check extension in the form "/scgi_pattern" */
15430                 if (*(extension->key->ptr) == '/' && strncmp(fn->ptr, extension->key->ptr, ct_len) == 0) {
15431                         break;
15432 @@ -2710,17 +2707,17 @@
15433         if (k == p->conf.exts->used) {
15434                 return HANDLER_GO_ON;
15435         }
15436 -       
15437 +
15438         /* get best server */
15439         for (k = 0, ndx = -1; k < extension->used; k++) {
15440                 scgi_extension_host *host = extension->hosts[k];
15441 -               
15442 +
15443                 /* we should have at least one proc that can do somthing */
15444                 if (host->active_procs == 0) continue;
15445  
15446                 if (used == -1 || host->load < used) {
15447                         used = host->load;
15448 -                       
15449 +
15450                         ndx = k;
15451                 }
15452         }
15453 @@ -2728,12 +2725,12 @@
15454         /* found a server */
15455         if (ndx != -1) {
15456                 scgi_extension_host *host = extension->hosts[ndx];
15457 -               
15458 -               /* 
15459 -                * if check-local is disabled, use the uri.path handler 
15460 -                * 
15461 +
15462 +               /*
15463 +                * if check-local is disabled, use the uri.path handler
15464 +                *
15465                  */
15466 -               
15467 +
15468                 /* init handler-context */
15469                 if (uri_path_handler) {
15470                         if (host->check_local == 0) {
15471 @@ -2741,7 +2738,7 @@
15472                                 char *pathinfo;
15473  
15474                                 hctx = handler_ctx_init();
15475 -                               
15476 +
15477                                 hctx->remote_conn      = con;
15478                                 hctx->plugin_data      = p;
15479                                 hctx->host             = host;
15480 @@ -2749,45 +2746,45 @@
15481  
15482                                 hctx->conf.exts        = p->conf.exts;
15483                                 hctx->conf.debug       = p->conf.debug;
15484 -                               
15485 +
15486                                 con->plugin_ctx[p->id] = hctx;
15487 -                               
15488 +
15489                                 host->load++;
15490 -                               
15491 +
15492                                 con->mode = p->id;
15493  
15494                                 if (con->conf.log_request_handling) {
15495                                         log_error_write(srv, __FILE__, __LINE__, "s", "handling it in mod_scgi");
15496                                 }
15497  
15498 -                               /* the prefix is the SCRIPT_NAME, 
15499 +                               /* the prefix is the SCRIPT_NAME,
15500                                  * everthing from start to the next slash
15501                                  * this is important for check-local = "disable"
15502 -                                * 
15503 +                                *
15504                                  * if prefix = /admin.fcgi
15505 -                                * 
15506 +                                *
15507                                  * /admin.fcgi/foo/bar
15508 -                                * 
15509 +                                *
15510                                  * SCRIPT_NAME = /admin.fcgi
15511                                  * PATH_INFO   = /foo/bar
15512 -                                * 
15513 +                                *
15514                                  * if prefix = /fcgi-bin/
15515 -                                * 
15516 +                                *
15517                                  * /fcgi-bin/foo/bar
15518 -                                * 
15519 +                                *
15520                                  * SCRIPT_NAME = /fcgi-bin/foo
15521                                  * PATH_INFO   = /bar
15522 -                                * 
15523 +                                *
15524                                  */
15525 -                               
15526 +
15527                                 /* the rewrite is only done for /prefix/? matches */
15528                                 if (extension->key->ptr[0] == '/' &&
15529                                     con->uri.path->used > extension->key->used &&
15530                                     NULL != (pathinfo = strchr(con->uri.path->ptr + extension->key->used - 1, '/'))) {
15531 -                                       /* rewrite uri.path and pathinfo */ 
15532 -                                       
15533 +                                       /* rewrite uri.path and pathinfo */
15534 +
15535                                         buffer_copy_string(con->request.pathinfo, pathinfo);
15536 -                                       
15537 +
15538                                         con->uri.path->used -= con->request.pathinfo->used - 1;
15539                                         con->uri.path->ptr[con->uri.path->used - 1] = '\0';
15540                                 }
15541 @@ -2796,21 +2793,21 @@
15542                 } else {
15543                         handler_ctx *hctx;
15544                         hctx = handler_ctx_init();
15545 -                       
15546 +
15547                         hctx->remote_conn      = con;
15548                         hctx->plugin_data      = p;
15549                         hctx->host             = host;
15550                         hctx->proc             = NULL;
15551 -                       
15552 +
15553                         hctx->conf.exts        = p->conf.exts;
15554                         hctx->conf.debug       = p->conf.debug;
15555 -                       
15556 +
15557                         con->plugin_ctx[p->id] = hctx;
15558 -                       
15559 +
15560                         host->load++;
15561 -                       
15562 +
15563                         con->mode = p->id;
15564 -                       
15565 +
15566                         if (con->conf.log_request_handling) {
15567                                 log_error_write(srv, __FILE__, __LINE__, "s", "handling it in mod_fastcgi");
15568                         }
15569 @@ -2821,11 +2818,11 @@
15570                 /* no handler found */
15571                 buffer_reset(con->physical.path);
15572                 con->http_status = 500;
15573 -               
15574 -               log_error_write(srv, __FILE__, __LINE__,  "sb", 
15575 -                               "no fcgi-handler found for:", 
15576 +
15577 +               log_error_write(srv, __FILE__, __LINE__,  "sb",
15578 +                               "no fcgi-handler found for:",
15579                                 fn);
15580 -               
15581 +
15582                 return HANDLER_FINISHED;
15583         }
15584         return HANDLER_GO_ON;
15585 @@ -2844,19 +2841,19 @@
15586  JOBLIST_FUNC(mod_scgi_handle_joblist) {
15587         plugin_data *p = p_d;
15588         handler_ctx *hctx = con->plugin_ctx[p->id];
15589 -       
15590 +
15591         if (hctx == NULL) return HANDLER_GO_ON;
15592  
15593         if (hctx->fd != -1) {
15594                 switch (hctx->state) {
15595                 case FCGI_STATE_READ:
15596                         fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
15597 -                       
15598 +
15599                         break;
15600                 case FCGI_STATE_CONNECT:
15601                 case FCGI_STATE_WRITE:
15602                         fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
15603 -                       
15604 +
15605                         break;
15606                 case FCGI_STATE_INIT:
15607                         /* at reconnect */
15608 @@ -2873,21 +2870,21 @@
15609  
15610  static handler_t scgi_connection_close_callback(server *srv, connection *con, void *p_d) {
15611         plugin_data *p = p_d;
15612 -       
15613 +
15614         return scgi_connection_close(srv, con->plugin_ctx[p->id]);
15615  }
15616  
15617  TRIGGER_FUNC(mod_scgi_handle_trigger) {
15618         plugin_data *p = p_d;
15619         size_t i, j, n;
15620 -       
15621 -       
15622 +
15623 +
15624         /* perhaps we should kill a connect attempt after 10-15 seconds
15625 -        * 
15626 +        *
15627          * currently we wait for the TCP timeout which is on Linux 180 seconds
15628 -        * 
15629 -        * 
15630 -        * 
15631 +        *
15632 +        *
15633 +        *
15634          */
15635  
15636         /* check all childs if they are still up */
15637 @@ -2904,47 +2901,47 @@
15638                         scgi_extension *ex;
15639  
15640                         ex = exts->exts[j];
15641 -                       
15642 +
15643                         for (n = 0; n < ex->used; n++) {
15644 -                               
15645 +
15646                                 scgi_proc *proc;
15647                                 unsigned long sum_load = 0;
15648                                 scgi_extension_host *host;
15649 -                               
15650 +
15651                                 host = ex->hosts[n];
15652 -                               
15653 +
15654                                 scgi_restart_dead_procs(srv, p, host);
15655 -                               
15656 +
15657                                 for (proc = host->first; proc; proc = proc->next) {
15658                                         sum_load += proc->load;
15659                                 }
15660 -                               
15661 +
15662                                 if (host->num_procs &&
15663                                     host->num_procs < host->max_procs &&
15664                                     (sum_load / host->num_procs) > host->max_load_per_proc) {
15665                                         /* overload, spawn new child */
15666                                         scgi_proc *fp = NULL;
15667 -                                       
15668 +
15669                                         if (p->conf.debug) {
15670 -                                               log_error_write(srv, __FILE__, __LINE__, "s", 
15671 +                                               log_error_write(srv, __FILE__, __LINE__, "s",
15672                                                                 "overload detected, spawning a new child");
15673                                         }
15674 -                                       
15675 +
15676                                         for (fp = host->unused_procs; fp && fp->pid != 0; fp = fp->next);
15677 -                                       
15678 +
15679                                         if (fp) {
15680                                                 if (fp == host->unused_procs) host->unused_procs = fp->next;
15681 -                                               
15682 +
15683                                                 if (fp->next) fp->next->prev = NULL;
15684 -                                               
15685 +
15686                                                 host->max_id++;
15687                                         } else {
15688                                                 fp = scgi_process_init();
15689                                                 fp->id = host->max_id++;
15690                                         }
15691 -                                       
15692 +
15693                                         host->num_procs++;
15694 -                                       
15695 +
15696                                         if (buffer_is_empty(host->unixsocket)) {
15697                                                 fp->port = host->port + fp->id;
15698                                         } else {
15699 @@ -2952,13 +2949,13 @@
15700                                                 buffer_append_string(fp->socket, "-");
15701                                                 buffer_append_long(fp->socket, fp->id);
15702                                         }
15703 -                                       
15704 +
15705                                         if (scgi_spawn_connection(srv, p, host, fp)) {
15706                                                 log_error_write(srv, __FILE__, __LINE__, "s",
15707                                                                 "ERROR: spawning fcgi failed.");
15708                                                 return HANDLER_ERROR;
15709                                         }
15710 -                                       
15711 +
15712                                         fp->prev = NULL;
15713                                         fp->next = host->first;
15714                                         if (host->first) {
15715 @@ -2966,56 +2963,57 @@
15716                                         }
15717                                         host->first = fp;
15718                                 }
15719 -                               
15720 +
15721                                 for (proc = host->first; proc; proc = proc->next) {
15722                                         if (proc->load != 0) break;
15723                                         if (host->num_procs <= host->min_procs) break;
15724                                         if (proc->pid == 0) continue;
15725 -                                       
15726 +#ifndef _WIN32
15727                                         if (srv->cur_ts - proc->last_used > host->idle_timeout) {
15728                                                 /* a proc is idling for a long time now,
15729                                                  * terminated it */
15730 -                                               
15731 +
15732                                                 if (p->conf.debug) {
15733 -                                                       log_error_write(srv, __FILE__, __LINE__, "ssbsd", 
15734 -                                                                       "idle-timeout reached, terminating child:", 
15735 -                                                                       "socket:", proc->socket, 
15736 +                                                       log_error_write(srv, __FILE__, __LINE__, "ssbsd",
15737 +                                                                       "idle-timeout reached, terminating child:",
15738 +                                                                       "socket:", proc->socket,
15739                                                                         "pid", proc->pid);
15740                                                 }
15741 -                                               
15742 -                                               
15743 +
15744 +
15745                                                 if (proc->next) proc->next->prev = proc->prev;
15746                                                 if (proc->prev) proc->prev->next = proc->next;
15747 -                                               
15748 +
15749                                                 if (proc->prev == NULL) host->first = proc->next;
15750 -                                               
15751 +
15752                                                 proc->prev = NULL;
15753                                                 proc->next = host->unused_procs;
15754 -                                               
15755 +
15756                                                 if (host->unused_procs) host->unused_procs->prev = proc;
15757                                                 host->unused_procs = proc;
15758 -                                               
15759 +
15760                                                 kill(proc->pid, SIGTERM);
15761 -                                               
15762 +
15763                                                 proc->state = PROC_STATE_KILLED;
15764 -                                               
15765 -                                               log_error_write(srv, __FILE__, __LINE__, "ssbsd", 
15766 -                                                                       "killed:", 
15767 -                                                                       "socket:", proc->socket, 
15768 +
15769 +                                               log_error_write(srv, __FILE__, __LINE__, "ssbsd",
15770 +                                                                       "killed:",
15771 +                                                                       "socket:", proc->socket,
15772                                                                         "pid", proc->pid);
15773 -                                               
15774 +
15775                                                 host->num_procs--;
15776 -                                               
15777 +
15778                                                 /* proc is now in unused, let the next second handle the next process */
15779                                                 break;
15780 -                                       }       
15781 +                                       }
15782 +#endif
15783                                 }
15784 -                               
15785 +
15786                                 for (proc = host->unused_procs; proc; proc = proc->next) {
15787                                         int status;
15788 -                                       
15789 +
15790                                         if (proc->pid == 0) continue;
15791 -                                       
15792 +#ifndef _WIN32
15793                                         switch (waitpid(proc->pid, &status, WNOHANG)) {
15794                                         case 0:
15795                                                 /* child still running after timeout, good */
15796 @@ -3023,10 +3021,10 @@
15797                                         case -1:
15798                                                 if (errno != EINTR) {
15799                                                         /* no PID found ? should never happen */
15800 -                                                       log_error_write(srv, __FILE__, __LINE__, "sddss", 
15801 +                                                       log_error_write(srv, __FILE__, __LINE__, "sddss",
15802                                                                         "pid ", proc->pid, proc->state,
15803                                                                         "not found:", strerror(errno));
15804 -                                                       
15805 +
15806  #if 0
15807                                                         if (errno == ECHILD) {
15808                                                                 /* someone else has cleaned up for us */
15809 @@ -3040,25 +3038,26 @@
15810                                                 /* the child should not terminate at all */
15811                                                 if (WIFEXITED(status)) {
15812                                                         if (proc->state != PROC_STATE_KILLED) {
15813 -                                                               log_error_write(srv, __FILE__, __LINE__, "sdb", 
15814 -                                                                               "child exited:", 
15815 +                                                               log_error_write(srv, __FILE__, __LINE__, "sdb",
15816 +                                                                               "child exited:",
15817                                                                                 WEXITSTATUS(status), proc->socket);
15818                                                         }
15819                                                 } else if (WIFSIGNALED(status)) {
15820                                                         if (WTERMSIG(status) != SIGTERM) {
15821 -                                                               log_error_write(srv, __FILE__, __LINE__, "sd", 
15822 -                                                                               "child signaled:", 
15823 +                                                               log_error_write(srv, __FILE__, __LINE__, "sd",
15824 +                                                                               "child signaled:",
15825                                                                                 WTERMSIG(status));
15826                                                         }
15827                                                 } else {
15828 -                                                       log_error_write(srv, __FILE__, __LINE__, "sd", 
15829 -                                                                       "child died somehow:", 
15830 +                                                       log_error_write(srv, __FILE__, __LINE__, "sd",
15831 +                                                                       "child died somehow:",
15832                                                                         status);
15833                                                 }
15834                                                 proc->pid = 0;
15835                                                 proc->state = PROC_STATE_UNSET;
15836                                                 host->max_id--;
15837                                         }
15838 +#endif
15839                                 }
15840                         }
15841                 }
15842 @@ -3082,8 +3081,8 @@
15843         p->handle_subrequest       = mod_scgi_handle_subrequest;
15844         p->handle_joblist          = mod_scgi_handle_joblist;
15845         p->handle_trigger          = mod_scgi_handle_trigger;
15846 -       
15847 +
15848         p->data         = NULL;
15849 -       
15850 +
15851         return 0;
15852  }
15853
15854 Property changes on: src/mod_scgi.c
15855 ___________________________________________________________________
15856 Name: svn:eol-style
15857    + native
15858
15859 Index: src/fastcgi.h
15860 ===================================================================
15861 --- src/fastcgi.h       (.../tags/lighttpd-1.4.11)      (revision 1159)
15862 +++ src/fastcgi.h       (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
15863 @@ -1,4 +1,4 @@
15864 -/* 
15865 +/*
15866   * fastcgi.h --
15867   *
15868   *     Defines for the FastCGI protocol.
15869 @@ -123,7 +123,7 @@
15870  
15871  
15872  typedef struct {
15873 -    unsigned char type;    
15874 +    unsigned char type;
15875      unsigned char reserved[7];
15876  } FCGI_UnknownTypeBody;
15877  
15878
15879 Property changes on: src/fastcgi.h
15880 ___________________________________________________________________
15881 Name: svn:eol-style
15882    + native
15883
15884 Index: src/etag.h
15885 ===================================================================
15886 --- src/etag.h  (.../tags/lighttpd-1.4.11)      (revision 1159)
15887 +++ src/etag.h  (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
15888 @@ -3,13 +3,12 @@
15889  
15890  #include <sys/types.h>
15891  #include <sys/stat.h>
15892 -#include <unistd.h>
15893  
15894  #include "buffer.h"
15895  
15896  int etag_is_equal(buffer *etag, const char *matches);
15897  int etag_create(buffer *etag, struct stat *st);
15898  int etag_mutate(buffer *mut, buffer *etag);
15899 -       
15900  
15901 +
15902  #endif
15903
15904 Property changes on: src/etag.h
15905 ___________________________________________________________________
15906 Name: svn:eol-style
15907    + native
15908
15909 Index: src/keyvalue.c
15910 ===================================================================
15911 --- src/keyvalue.c      (.../tags/lighttpd-1.4.11)      (revision 1159)
15912 +++ src/keyvalue.c      (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
15913 @@ -87,7 +87,8 @@
15914         { 504, "Gateway Timeout" },
15915         { 505, "HTTP Version Not Supported" },
15916         { 507, "Insufficient Storage" }, /* WebDAV */
15917 -       
15918 +       { 509, "Bandwidth Limit exceeded" },
15919 +
15920         { -1, NULL }
15921  };
15922  
15923 @@ -102,12 +103,12 @@
15924         { 501, "501.html" },
15925         { 503, "503.html" },
15926         { 505, "505.html" },
15927 -       
15928 +
15929         { -1, NULL }
15930  };
15931  
15932  
15933 -const char *keyvalue_get_value(keyvalue *kv, int k) { 
15934 +const char *keyvalue_get_value(keyvalue *kv, int k) {
15935         int i;
15936         for (i = 0; kv[i].value; i++) {
15937                 if (kv[i].key == k) return kv[i].value;
15938 @@ -115,7 +116,7 @@
15939         return NULL;
15940  }
15941  
15942 -int keyvalue_get_key(keyvalue *kv, const char *s) { 
15943 +int keyvalue_get_key(keyvalue *kv, const char *s) {
15944         int i;
15945         for (i = 0; kv[i].value; i++) {
15946                 if (0 == strcmp(kv[i].value, s)) return kv[i].key;
15947 @@ -125,9 +126,9 @@
15948  
15949  keyvalue_buffer *keyvalue_buffer_init(void) {
15950         keyvalue_buffer *kvb;
15951 -       
15952 +
15953         kvb = calloc(1, sizeof(*kvb));
15954 -       
15955 +
15956         return kvb;
15957  }
15958  
15959 @@ -135,49 +136,49 @@
15960         size_t i;
15961         if (kvb->size == 0) {
15962                 kvb->size = 4;
15963 -               
15964 +
15965                 kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
15966 -               
15967 +
15968                 for(i = 0; i < kvb->size; i++) {
15969                         kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
15970                 }
15971         } else if (kvb->used == kvb->size) {
15972                 kvb->size += 4;
15973 -               
15974 +
15975                 kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
15976 -               
15977 +
15978                 for(i = kvb->used; i < kvb->size; i++) {
15979                         kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
15980                 }
15981         }
15982 -       
15983 +
15984         kvb->kv[kvb->used]->key = key;
15985         kvb->kv[kvb->used]->value = strdup(value);
15986 -       
15987 +
15988         kvb->used++;
15989 -       
15990 +
15991         return 0;
15992  }
15993  
15994  void keyvalue_buffer_free(keyvalue_buffer *kvb) {
15995         size_t i;
15996 -       
15997 +
15998         for (i = 0; i < kvb->size; i++) {
15999                 if (kvb->kv[i]->value) free(kvb->kv[i]->value);
16000                 free(kvb->kv[i]);
16001         }
16002 -       
16003 +
16004         if (kvb->kv) free(kvb->kv);
16005 -       
16006 +
16007         free(kvb);
16008  }
16009  
16010  
16011  s_keyvalue_buffer *s_keyvalue_buffer_init(void) {
16012         s_keyvalue_buffer *kvb;
16013 -       
16014 +
16015         kvb = calloc(1, sizeof(*kvb));
16016 -       
16017 +
16018         return kvb;
16019  }
16020  
16021 @@ -186,50 +187,50 @@
16022         if (kvb->size == 0) {
16023                 kvb->size = 4;
16024                 kvb->used = 0;
16025 -               
16026 +
16027                 kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
16028 -               
16029 +
16030                 for(i = 0; i < kvb->size; i++) {
16031                         kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
16032                 }
16033         } else if (kvb->used == kvb->size) {
16034                 kvb->size += 4;
16035 -               
16036 +
16037                 kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
16038 -               
16039 +
16040                 for(i = kvb->used; i < kvb->size; i++) {
16041                         kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
16042                 }
16043         }
16044 -       
16045 +
16046         kvb->kv[kvb->used]->key = key ? strdup(key) : NULL;
16047         kvb->kv[kvb->used]->value = strdup(value);
16048 -       
16049 +
16050         kvb->used++;
16051 -       
16052 +
16053         return 0;
16054  }
16055  
16056  void s_keyvalue_buffer_free(s_keyvalue_buffer *kvb) {
16057         size_t i;
16058 -       
16059 +
16060         for (i = 0; i < kvb->size; i++) {
16061                 if (kvb->kv[i]->key) free(kvb->kv[i]->key);
16062                 if (kvb->kv[i]->value) free(kvb->kv[i]->value);
16063                 free(kvb->kv[i]);
16064         }
16065 -       
16066 +
16067         if (kvb->kv) free(kvb->kv);
16068 -       
16069 +
16070         free(kvb);
16071  }
16072  
16073  
16074  httpauth_keyvalue_buffer *httpauth_keyvalue_buffer_init(void) {
16075         httpauth_keyvalue_buffer *kvb;
16076 -       
16077 +
16078         kvb = calloc(1, sizeof(*kvb));
16079 -       
16080 +
16081         return kvb;
16082  }
16083  
16084 @@ -237,42 +238,42 @@
16085         size_t i;
16086         if (kvb->size == 0) {
16087                 kvb->size = 4;
16088 -               
16089 +
16090                 kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
16091 -               
16092 +
16093                 for(i = 0; i < kvb->size; i++) {
16094                         kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
16095                 }
16096         } else if (kvb->used == kvb->size) {
16097                 kvb->size += 4;
16098 -               
16099 +
16100                 kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
16101 -               
16102 +
16103                 for(i = kvb->used; i < kvb->size; i++) {
16104                         kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
16105                 }
16106         }
16107 -       
16108 +
16109         kvb->kv[kvb->used]->key = strdup(key);
16110         kvb->kv[kvb->used]->realm = strdup(realm);
16111         kvb->kv[kvb->used]->type = type;
16112 -       
16113 +
16114         kvb->used++;
16115 -       
16116 +
16117         return 0;
16118  }
16119  
16120  void httpauth_keyvalue_buffer_free(httpauth_keyvalue_buffer *kvb) {
16121         size_t i;
16122 -       
16123 +
16124         for (i = 0; i < kvb->size; i++) {
16125                 if (kvb->kv[i]->key) free(kvb->kv[i]->key);
16126                 if (kvb->kv[i]->realm) free(kvb->kv[i]->realm);
16127                 free(kvb->kv[i]);
16128         }
16129 -       
16130 +
16131         if (kvb->kv) free(kvb->kv);
16132 -       
16133 +
16134         free(kvb);
16135  }
16136  
16137 @@ -306,9 +307,9 @@
16138  
16139  pcre_keyvalue_buffer *pcre_keyvalue_buffer_init(void) {
16140         pcre_keyvalue_buffer *kvb;
16141 -       
16142 +
16143         kvb = calloc(1, sizeof(*kvb));
16144 -       
16145 +
16146         return kvb;
16147  }
16148  
16149 @@ -319,46 +320,46 @@
16150         int erroff;
16151         pcre_keyvalue *kv;
16152  #endif
16153 -       
16154 +
16155         if (!key) return -1;
16156  
16157  #ifdef HAVE_PCRE_H
16158         if (kvb->size == 0) {
16159                 kvb->size = 4;
16160                 kvb->used = 0;
16161 -               
16162 +
16163                 kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
16164 -               
16165 +
16166                 for(i = 0; i < kvb->size; i++) {
16167                         kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
16168                 }
16169         } else if (kvb->used == kvb->size) {
16170                 kvb->size += 4;
16171 -               
16172 +
16173                 kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
16174 -               
16175 +
16176                 for(i = kvb->used; i < kvb->size; i++) {
16177                         kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
16178                 }
16179         }
16180 -       
16181 +
16182         kv = kvb->kv[kvb->used];
16183         if (NULL == (kv->key = pcre_compile(key,
16184                                           0, &errptr, &erroff, NULL))) {
16185 -               
16186 +
16187                 fprintf(stderr, "%s.%d: rexexp compilation error at %s\n", __FILE__, __LINE__, errptr);
16188                 return -1;
16189         }
16190  
16191 -       if (NULL == (kv->key_extra = pcre_study(kv->key, 0, &errptr)) &&  
16192 +       if (NULL == (kv->key_extra = pcre_study(kv->key, 0, &errptr)) &&
16193                         errptr != NULL) {
16194                 return -1;
16195         }
16196 -       
16197 +
16198         kv->value = buffer_init_string(value);
16199 -       
16200 +
16201         kvb->used++;
16202 -       
16203 +
16204         return 0;
16205  #else
16206         UNUSED(kvb);
16207 @@ -380,9 +381,9 @@
16208                 if (kv->value) buffer_free(kv->value);
16209                 free(kv);
16210         }
16211 -       
16212 +
16213         if (kvb->kv) free(kvb->kv);
16214  #endif
16215 -       
16216 +
16217         free(kvb);
16218  }
16219
16220 Property changes on: src/keyvalue.c
16221 ___________________________________________________________________
16222 Name: svn:eol-style
16223    + native
16224
16225 Index: src/mod_mysql_vhost.c
16226 ===================================================================
16227 --- src/mod_mysql_vhost.c       (.../tags/lighttpd-1.4.11)      (revision 1159)
16228 +++ src/mod_mysql_vhost.c       (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
16229 @@ -1,13 +1,18 @@
16230 -#include <unistd.h>
16231  #include <stdio.h>
16232  #include <errno.h>
16233  #include <fcntl.h>
16234 -#include <strings.h>
16235 +#include <string.h>
16236  
16237  #ifdef HAVE_CONFIG_H
16238  #include "config.h"
16239  #endif
16240  
16241 +#ifdef HAVE_MYSQL_H 
16242 +# ifdef HAVE_LIBMYSQL
16243 +#  define HAVE_MYSQL
16244 +# endif
16245 +#endif
16246 +
16247  #ifdef HAVE_MYSQL
16248  #include <mysql.h>
16249  #endif
16250 @@ -16,61 +21,40 @@
16251  #include "log.h"
16252  
16253  #include "stat_cache.h"
16254 -#ifdef DEBUG_MOD_MYSQL_VHOST
16255 -#define DEBUG
16256 -#endif
16257 +#include "sys-files.h"
16258  
16259 -/*
16260 - * Plugin for lighttpd to use MySQL 
16261 - *   for domain to directory lookups,
16262 - *   i.e virtual hosts (vhosts).
16263 - *   
16264 - * Optionally sets fcgi_offset and fcgi_arg 
16265 - *   in preparation for fcgi.c to handle 
16266 - *   per-user fcgi chroot jails.
16267 - *
16268 - * /ada@riksnet.se 2004-12-06
16269 - */
16270 +#include "mod_sql_vhost_core.h"
16271  
16272  #ifdef HAVE_MYSQL
16273 +
16274 +#define CORE_PLUGIN "mod_sql_vhost_core"
16275 +
16276  typedef struct {
16277         MYSQL   *mysql;
16278 -       
16279 -       buffer  *mydb;
16280 -       buffer  *myuser;
16281 -       buffer  *mypass;
16282 -       buffer  *mysock;
16283 -       
16284 -       buffer  *hostname;
16285 -       unsigned short port;
16286 -       
16287 +
16288         buffer  *mysql_pre;
16289         buffer  *mysql_post;
16290 +
16291 +       mod_sql_vhost_core_plugin_config *core;
16292  } plugin_config;
16293  
16294  /* global plugin data */
16295  typedef struct {
16296         PLUGIN_DATA;
16297 -       
16298 +
16299         buffer  *tmp_buf;
16300 -       
16301 +
16302         plugin_config **config_storage;
16303 -       
16304 -       plugin_config conf; 
16305 +
16306 +       plugin_config conf;
16307  } plugin_data;
16308  
16309 -/* per connection plugin data */
16310 -typedef struct {
16311 -       buffer  *server_name;
16312 -       buffer  *document_root;
16313 -       buffer  *fcgi_arg;
16314 -       unsigned fcgi_offset;
16315 -} plugin_connection_data;
16316 +SQLVHOST_BACKEND_GETVHOST(mod_mysql_vhost_get_vhost); 
16317  
16318  /* init the plugin data */
16319  INIT_FUNC(mod_mysql_vhost_init) {
16320         plugin_data *p;
16321 -       
16322 +
16323         p = calloc(1, sizeof(*p));
16324  
16325         p->tmp_buf = buffer_init();
16326 @@ -83,144 +67,77 @@
16327         plugin_data *p = p_d;
16328  
16329         UNUSED(srv);
16330 -       
16331 -#ifdef DEBUG
16332 -       log_error_write(srv, __FILE__, __LINE__, "ss", 
16333 -               "mod_mysql_vhost_cleanup", p ? "yes" : "NO");
16334 -#endif
16335 +
16336         if (!p) return HANDLER_GO_ON;
16337 -       
16338 +
16339         if (p->config_storage) {
16340                 size_t i;
16341                 for (i = 0; i < srv->config_context->used; i++) {
16342                         plugin_config *s = p->config_storage[i];
16343  
16344                         if (!s) continue;
16345 -                       
16346 +
16347                         mysql_close(s->mysql);
16348 -                       
16349 -                       buffer_free(s->mydb);
16350 -                       buffer_free(s->myuser);
16351 -                       buffer_free(s->mypass);
16352 -                       buffer_free(s->mysock);
16353 +
16354                         buffer_free(s->mysql_pre);
16355                         buffer_free(s->mysql_post);
16356 -                       
16357 +
16358                         free(s);
16359                 }
16360                 free(p->config_storage);
16361         }
16362         buffer_free(p->tmp_buf);
16363 -       
16364 +
16365         free(p);
16366  
16367         return HANDLER_GO_ON;
16368  }
16369  
16370 -/* handle the plugin per connection data */
16371 -static void* mod_mysql_vhost_connection_data(server *srv, connection *con, void *p_d)
16372 -{
16373 -       plugin_data *p = p_d;
16374 -       plugin_connection_data *c = con->plugin_ctx[p->id];
16375 -
16376 -       UNUSED(srv);
16377 -
16378 -#ifdef DEBUG
16379 -        log_error_write(srv, __FILE__, __LINE__, "ss", 
16380 -               "mod_mysql_connection_data", c ? "old" : "NEW");
16381 -#endif
16382 -
16383 -       if (c) return c;
16384 -       c = calloc(1, sizeof(*c));
16385 -
16386 -       c->server_name = buffer_init();
16387 -       c->document_root = buffer_init();
16388 -       c->fcgi_arg = buffer_init();
16389 -       c->fcgi_offset = 0;
16390 -
16391 -       return con->plugin_ctx[p->id] = c;
16392 -}
16393 -
16394 -/* destroy the plugin per connection data */
16395 -CONNECTION_FUNC(mod_mysql_vhost_handle_connection_close) {
16396 -       plugin_data *p = p_d;
16397 -       plugin_connection_data *c = con->plugin_ctx[p->id];
16398 -
16399 -       UNUSED(srv);
16400 -
16401 -#ifdef DEBUG
16402 -       log_error_write(srv, __FILE__, __LINE__, "ss", 
16403 -               "mod_mysql_vhost_handle_connection_close", c ? "yes" : "NO");
16404 -#endif
16405 -       
16406 -       if (!c) return HANDLER_GO_ON;
16407 -
16408 -       buffer_free(c->server_name);
16409 -       buffer_free(c->document_root);
16410 -       buffer_free(c->fcgi_arg);
16411 -       c->fcgi_offset = 0;
16412 -
16413 -       free(c);
16414 -
16415 -       con->plugin_ctx[p->id] = NULL;
16416 -       return HANDLER_GO_ON;
16417 -}
16418 -
16419  /* set configuration values */
16420  SERVER_FUNC(mod_mysql_vhost_set_defaults) {
16421         plugin_data *p = p_d;
16422 +       mod_sql_vhost_core_plugin_data *core_config;
16423  
16424 -       char *qmark;
16425         size_t i = 0;
16426  
16427 -       config_values_t cv[] = {
16428 -               { "mysql-vhost.db",     NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER },
16429 -               { "mysql-vhost.user",   NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER },
16430 -               { "mysql-vhost.pass",   NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER },
16431 -               { "mysql-vhost.sock",   NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER },
16432 -               { "mysql-vhost.sql",    NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER },
16433 -               { "mysql-vhost.hostname", NULL, T_CONFIG_STRING,T_CONFIG_SCOPE_SERVER },
16434 -               { "mysql-vhost.port",   NULL, T_CONFIG_SHORT,   T_CONFIG_SCOPE_SERVER },
16435 -                { NULL,                        NULL, T_CONFIG_UNSET,   T_CONFIG_SCOPE_UNSET }
16436 -        };
16437 -       
16438 +       /* our very own plugin storage, one entry for each conditional
16439 +        * 
16440 +        * srv->config_context->used is the number of conditionals
16441 +        * */
16442         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
16443 -       
16444 +
16445 +       /* get the config of the core-plugin */
16446 +       core_config = plugin_get_config(srv, CORE_PLUGIN);
16447 +
16448 +
16449 +       /* walk through all conditionals and check for assignments */
16450         for (i = 0; i < srv->config_context->used; i++) {
16451                 plugin_config *s;
16452                 buffer *sel;
16453 -               
16454 -               
16455 +               char *qmark;
16456 +
16457 +               /* get the config from the core plugin for this conditional-context */
16458                 s = calloc(1, sizeof(plugin_config));
16459 -               s->mydb = buffer_init();
16460 -               s->myuser = buffer_init();
16461 -               s->mypass = buffer_init();
16462 -               s->mysock = buffer_init();
16463 -               s->hostname = buffer_init();
16464 -               s->port   = 0;               /* default port for mysql */
16465 -               sel = buffer_init();
16466 -               s->mysql = NULL;
16467 +
16468 +               s->core = core_config->config_storage[i];
16469                 
16470 +               s->mysql = NULL;
16471 +
16472                 s->mysql_pre = buffer_init();
16473                 s->mysql_post = buffer_init();
16474 -               
16475 -               cv[0].destination = s->mydb;
16476 -               cv[1].destination = s->myuser;
16477 -               cv[2].destination = s->mypass;
16478 -               cv[3].destination = s->mysock;
16479 -               cv[4].destination = sel;
16480 -               cv[5].destination = s->hostname;
16481 -               cv[6].destination = &(s->port);
16482 -               
16483 +
16484                 p->config_storage[i] = s;
16485 -               
16486 -               if (config_insert_values_global(srv, 
16487 -                       ((data_config *)srv->config_context->data[i])->value,
16488 -                       cv)) return HANDLER_ERROR;
16489 -               
16490 -               s->mysql_pre = buffer_init();
16491 -               s->mysql_post = buffer_init();
16492 -               
16493 +
16494 +               /* check if we are the plugin for this backend */
16495 +               if (!buffer_is_equal_string(s->core->backend, CONST_STR_LEN("mysql"))) continue;
16496 +
16497 +               /* attach us to the core-plugin */
16498 +               s->core->backend_data = p;
16499 +               s->core->get_vhost = mod_mysql_vhost_get_vhost;
16500 +
16501 +               sel = buffer_init();
16502 +               buffer_copy_string_buffer(sel, s->core->select_vhost);
16503 +
16504                 if (sel->used && (qmark = index(sel->ptr, '?'))) {
16505                         *qmark = '\0';
16506                         buffer_copy_string(s->mysql_pre, sel->ptr);
16507 @@ -228,35 +145,35 @@
16508                 } else {
16509                         buffer_copy_string_buffer(s->mysql_pre, sel);
16510                 }
16511 -               
16512 +
16513                 /* required:
16514                  * - username
16515 -                * - database 
16516 -                * 
16517 +                * - database
16518 +                *
16519                  * optional:
16520                  * - password, default: empty
16521                  * - socket, default: mysql default
16522                  * - hostname, if set overrides socket
16523                  * - port, default: 3306
16524                  */
16525 -               
16526 +
16527                 /* all have to be set */
16528 -               if (!(buffer_is_empty(s->myuser) ||
16529 -                     buffer_is_empty(s->mydb))) {
16530 +               if (!(buffer_is_empty(s->core->user) ||
16531 +                     buffer_is_empty(s->core->db))) {
16532  
16533                         int fd;
16534 -               
16535 +
16536                         if (NULL == (s->mysql = mysql_init(NULL))) {
16537                                 log_error_write(srv, __FILE__, __LINE__, "s", "mysql_init() failed, exiting...");
16538 -                               
16539 +
16540                                 return HANDLER_ERROR;
16541                         }
16542 -#define FOO(x) (s->x->used ? s->x->ptr : NULL)
16543 -                       
16544 -                       if (!mysql_real_connect(s->mysql, FOO(hostname), FOO(myuser), FOO(mypass), 
16545 -                                               FOO(mydb), s->port, FOO(mysock), 0)) {
16546 +#define FOO(x) (s->core->x->used ? s->core->x->ptr : NULL)
16547 +
16548 +                       if (!mysql_real_connect(s->mysql, FOO(hostname), FOO(user), FOO(pass),
16549 +                                               FOO(db), s->core->port, FOO(sock), 0)) {
16550                                 log_error_write(srv, __FILE__, __LINE__, "s", mysql_error(s->mysql));
16551 -                               
16552 +
16553                                 return HANDLER_ERROR;
16554                         }
16555  #undef FOO
16556 @@ -265,61 +182,47 @@
16557                         /* otherwise we cannot be sure that mysql is fd i-1 */
16558                         if (-1 == (fd = open("/dev/null", 0))) {
16559                                 close(fd);
16560 -                               fcntl(fd-1, F_SETFD, FD_CLOEXEC); 
16561 +                               fcntl(fd-1, F_SETFD, FD_CLOEXEC);
16562                         }
16563                 }
16564         }
16565 -       
16566 -       
16567  
16568 +
16569 +
16570          return HANDLER_GO_ON;
16571  }
16572  
16573 -#define PATCH(x) \
16574 -       p->conf.x = s->x;
16575  static int mod_mysql_vhost_patch_connection(server *srv, connection *con, plugin_data *p) {
16576 -       size_t i, j;
16577 +       size_t i;
16578         plugin_config *s = p->config_storage[0];
16579 -       
16580 -       PATCH(mysql_pre);
16581 -       PATCH(mysql_post);
16582 -#ifdef HAVE_MYSQL
16583 -       PATCH(mysql);
16584 -#endif
16585 -       
16586 +
16587 +       PATCH_OPTION(mysql_pre);
16588 +       PATCH_OPTION(mysql_post);
16589 +       PATCH_OPTION(mysql);
16590 +
16591         /* skip the first, the global context */
16592         for (i = 1; i < srv->config_context->used; i++) {
16593                 data_config *dc = (data_config *)srv->config_context->data[i];
16594                 s = p->config_storage[i];
16595 -               
16596 +
16597                 /* condition didn't match */
16598                 if (!config_check_cond(srv, con, dc)) continue;
16599 -               
16600 -               /* merge config */
16601 -               for (j = 0; j < dc->value->used; j++) {
16602 -                       data_unset *du = dc->value->data[j];
16603 -                       
16604 -                       if (buffer_is_equal_string(du->key, CONST_STR_LEN("mysql-vhost.sql"))) {
16605 -                               PATCH(mysql_pre);
16606 -                               PATCH(mysql_post);
16607 -                       }
16608 -               }
16609 -               
16610 +
16611                 if (s->mysql) {
16612 -                       PATCH(mysql);
16613 +                       PATCH_OPTION(mysql);
16614 +                       PATCH_OPTION(mysql_pre);
16615 +                       PATCH_OPTION(mysql_post);
16616                 }
16617         }
16618 -       
16619 +
16620         return 0;
16621  }
16622 -#undef PATCH
16623  
16624 -
16625 -/* handle document root request */
16626 -CONNECTION_FUNC(mod_mysql_vhost_handle_docroot) {
16627 +/**
16628 + * get the vhost info from the database 
16629 + */
16630 +SQLVHOST_BACKEND_GETVHOST(mod_mysql_vhost_get_vhost) {
16631         plugin_data *p = p_d;
16632 -       plugin_connection_data *c;
16633 -       stat_cache_entry *sce;
16634  
16635         unsigned  cols;
16636         MYSQL_ROW row;
16637 @@ -332,13 +235,6 @@
16638  
16639         if (!p->conf.mysql) return HANDLER_GO_ON;
16640  
16641 -       /* sets up connection data if not done yet */
16642 -       c = mod_mysql_vhost_connection_data(srv, con, p_d);
16643 -
16644 -       /* check if cached this connection */
16645 -       if (c->server_name->used && /* con->uri.authority->used && */
16646 -            buffer_is_equal(c->server_name, con->uri.authority)) goto GO_ON;
16647 -
16648         /* build and run SQL query */
16649         buffer_copy_string_buffer(p->tmp_buf, p->conf.mysql_pre);
16650         if (p->conf.mysql_post->used) {
16651 @@ -347,77 +243,43 @@
16652         }
16653         if (mysql_query(p->conf.mysql, p->tmp_buf->ptr)) {
16654                 log_error_write(srv, __FILE__, __LINE__, "s", mysql_error(p->conf.mysql));
16655 -               goto ERR500;
16656 +
16657 +               mysql_free_result(result);
16658 +               return HANDLER_GO_ON;
16659         }
16660         result = mysql_store_result(p->conf.mysql);
16661         cols = mysql_num_fields(result);
16662         row = mysql_fetch_row(result);
16663 +
16664         if (!row || cols < 1) {
16665                 /* no such virtual host */
16666                 mysql_free_result(result);
16667                 return HANDLER_GO_ON;
16668         }
16669  
16670 -       /* sanity check that really is a directory */
16671 -       buffer_copy_string(p->tmp_buf, row[0]);
16672 -       BUFFER_APPEND_SLASH(p->tmp_buf);
16673 +       buffer_copy_string(docroot, row[0]);
16674  
16675 -       if (HANDLER_ERROR == stat_cache_get_entry(srv, con, p->tmp_buf, &sce)) {
16676 -               log_error_write(srv, __FILE__, __LINE__, "sb", strerror(errno), p->tmp_buf);
16677 -               goto ERR500;
16678 -       }
16679 -        if (!S_ISDIR(sce->st.st_mode)) {
16680 -               log_error_write(srv, __FILE__, __LINE__, "sb", "Not a directory", p->tmp_buf);
16681 -               goto ERR500;
16682 -       }
16683 -
16684 -       /* cache the data */
16685 -       buffer_copy_string_buffer(c->server_name, con->uri.authority);
16686 -       buffer_copy_string_buffer(c->document_root, p->tmp_buf);
16687 -
16688 -       /* fcgi_offset and fcgi_arg are optional */
16689 -       if (cols > 1 && row[1]) {
16690 -               c->fcgi_offset = atoi(row[1]);
16691 -               
16692 -               if (cols > 2 && row[2]) {
16693 -                       buffer_copy_string(c->fcgi_arg, row[2]);
16694 -               } else {
16695 -                       c->fcgi_arg->used = 0;
16696 -               }
16697 -       } else {
16698 -               c->fcgi_offset = c->fcgi_arg->used = 0;
16699 -       }
16700         mysql_free_result(result);
16701  
16702 -       /* fix virtual server and docroot */
16703 -GO_ON: buffer_copy_string_buffer(con->server_name, c->server_name);
16704 -       buffer_copy_string_buffer(con->physical.doc_root, c->document_root);
16705 -
16706 -#ifdef DEBUG
16707 -       log_error_write(srv, __FILE__, __LINE__, "sbbdb", 
16708 -               result ? "NOT CACHED" : "cached", 
16709 -               con->server_name, con->physical.doc_root,
16710 -               c->fcgi_offset, c->fcgi_arg);
16711 -#endif
16712 -       return HANDLER_GO_ON;   
16713 -
16714 -ERR500:        if (result) mysql_free_result(result);
16715 -       con->http_status = 500; /* Internal Error */
16716 -       return HANDLER_FINISHED;
16717 +       return HANDLER_GO_ON;
16718  }
16719  
16720  /* this function is called at dlopen() time and inits the callbacks */
16721  int mod_mysql_vhost_plugin_init(plugin *p) {
16722 +       data_string *ds;
16723 +       
16724         p->version     = LIGHTTPD_VERSION_ID;
16725         p->name                         = buffer_init_string("mysql_vhost");
16726  
16727         p->init                         = mod_mysql_vhost_init;
16728         p->cleanup                      = mod_mysql_vhost_cleanup;
16729 -       p->handle_request_done          = mod_mysql_vhost_handle_connection_close;
16730  
16731         p->set_defaults                 = mod_mysql_vhost_set_defaults;
16732 -       p->handle_docroot               = mod_mysql_vhost_handle_docroot;
16733         
16734 +       ds = data_string_init();
16735 +       buffer_copy_string(ds->value, CORE_PLUGIN);
16736 +       array_insert_unique(p->required_plugins, (data_unset *)ds);
16737 +
16738         return 0;
16739  }
16740  #else
16741 Index: src/request.c
16742 ===================================================================
16743 --- src/request.c       (.../tags/lighttpd-1.4.11)      (revision 1159)
16744 +++ src/request.c       (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
16745 @@ -10,15 +10,17 @@
16746  #include "keyvalue.h"
16747  #include "log.h"
16748  
16749 +#include "sys-strings.h"
16750 +
16751  static int request_check_hostname(server *srv, connection *con, buffer *host) {
16752         enum { DOMAINLABEL, TOPLABEL } stage = TOPLABEL;
16753         size_t i;
16754         int label_len = 0;
16755         size_t host_len;
16756         char *colon;
16757 -       int is_ip = -1; /* -1 don't know yet, 0 no, 1 yes */ 
16758 +       int is_ip = -1; /* -1 don't know yet, 0 no, 1 yes */
16759         int level = 0;
16760 -       
16761 +
16762         UNUSED(srv);
16763         UNUSED(con);
16764  
16765 @@ -32,17 +34,17 @@
16766          *       IPv6address   = "[" ... "]"
16767          *       port          = *digit
16768          */
16769 -       
16770 +
16771         /* no Host: */
16772         if (!host || host->used == 0) return 0;
16773 -       
16774 +
16775         host_len = host->used - 1;
16776 -       
16777 +
16778         /* IPv6 adress */
16779         if (host->ptr[0] == '[') {
16780                 char *c = host->ptr + 1;
16781                 int colon_cnt = 0;
16782 -               
16783 +
16784                 /* check portnumber */
16785                 for (; *c && *c != ']'; c++) {
16786                         if (*c == ':') {
16787 @@ -53,12 +55,12 @@
16788                                 return -1;
16789                         }
16790                 }
16791 -               
16792 +
16793                 /* missing ] */
16794                 if (!*c) {
16795                         return -1;
16796                 }
16797 -               
16798 +
16799                 /* check port */
16800                 if (*(c+1) == ':') {
16801                         for (c += 2; *c; c++) {
16802 @@ -69,39 +71,39 @@
16803                 }
16804                 return 0;
16805         }
16806 -       
16807 +
16808         if (NULL != (colon = memchr(host->ptr, ':', host_len))) {
16809                 char *c = colon + 1;
16810 -               
16811 +
16812                 /* check portnumber */
16813                 for (; *c; c++) {
16814                         if (!light_isdigit(*c)) return -1;
16815                 }
16816 -               
16817 +
16818                 /* remove the port from the host-len */
16819                 host_len = colon - host->ptr;
16820         }
16821 -       
16822 +
16823         /* Host is empty */
16824         if (host_len == 0) return -1;
16825 -       
16826 +
16827         /* scan from the right and skip the \0 */
16828         for (i = host_len - 1; i + 1 > 0; i--) {
16829                 const char c = host->ptr[i];
16830  
16831                 switch (stage) {
16832 -               case TOPLABEL: 
16833 +               case TOPLABEL:
16834                         if (c == '.') {
16835                                 /* only switch stage, if this is not the last character */
16836                                 if (i != host_len - 1) {
16837                                         if (label_len == 0) {
16838                                                 return -1;
16839                                         }
16840 -                                       
16841 +
16842                                         /* check the first character at right of the dot */
16843                                         if (is_ip == 0) {
16844                                                 if (!light_isalpha(host->ptr[i+1])) {
16845 -                                                       return -1; 
16846 +                                                       return -1;
16847                                                 }
16848                                         } else if (!light_isdigit(host->ptr[i+1])) {
16849                                                 is_ip = 0;
16850 @@ -111,9 +113,9 @@
16851                                                 /* just digits */
16852                                                 is_ip = 1;
16853                                         }
16854 -                                               
16855 +
16856                                         stage = DOMAINLABEL;
16857 -                                       
16858 +
16859                                         label_len = 0;
16860                                         level++;
16861                                 } else if (i == 0) {
16862 @@ -135,7 +137,7 @@
16863                                 }
16864                                 label_len++;
16865                         }
16866 -                       
16867 +
16868                         break;
16869                 case DOMAINLABEL:
16870                         if (is_ip == 1) {
16871 @@ -143,7 +145,7 @@
16872                                         if (label_len == 0) {
16873                                                 return -1;
16874                                         }
16875 -                                       
16876 +
16877                                         label_len = 0;
16878                                         level++;
16879                                 } else if (!light_isdigit(c)) {
16880 @@ -156,12 +158,12 @@
16881                                         if (label_len == 0) {
16882                                                 return -1;
16883                                         }
16884 -                                       
16885 +
16886                                         /* c is either - or alphanum here */
16887                                         if ('-' == host->ptr[i+1]) {
16888                                                 return -1;
16889                                         }
16890 -                                       
16891 +
16892                                         label_len = 0;
16893                                         level++;
16894                                 } else if (i == 0) {
16895 @@ -176,20 +178,20 @@
16896                                         label_len++;
16897                                 }
16898                         }
16899 -                       
16900 +
16901                         break;
16902                 }
16903         }
16904 -       
16905 +
16906         /* a IP has to consist of 4 parts */
16907         if (is_ip == 1 && level != 3) {
16908                 return -1;
16909         }
16910 -       
16911 +
16912         if (label_len == 0) {
16913                 return -1;
16914         }
16915 -       
16916 +
16917         return 0;
16918  }
16919  
16920 @@ -201,53 +203,53 @@
16921         char *s;
16922         size_t i;
16923         int state = 0;
16924 -       /*  
16925 -        * parse 
16926 -        * 
16927 +       /*
16928 +        * parse
16929 +        *
16930          * val1, val2, val3, val4
16931 -        * 
16932 +        *
16933          * into a array (more or less a explode() incl. striping of whitespaces
16934          */
16935 -       
16936 +
16937         if (b->used == 0) return 0;
16938 -       
16939 +
16940         s = b->ptr;
16941 -       
16942 +
16943         for (i =0; i < b->used - 1; ) {
16944                 char *start = NULL, *end = NULL;
16945                 data_string *ds;
16946 -               
16947 +
16948                 switch (state) {
16949                 case 0: /* ws */
16950 -                       
16951 +
16952                         /* skip ws */
16953                         for (; (*s == ' ' || *s == '\t') && i < b->used - 1; i++, s++);
16954 -                       
16955 -                       
16956 +
16957 +
16958                         state = 1;
16959                         break;
16960                 case 1: /* value */
16961                         start = s;
16962 -                       
16963 +
16964                         for (; *s != ',' && i < b->used - 1; i++, s++);
16965                         end = s - 1;
16966 -                       
16967 +
16968                         for (; (*end == ' ' || *end == '\t') && end > start; end--);
16969 -                       
16970 +
16971                         if (NULL == (ds = (data_string *)array_get_unused_element(vals, TYPE_STRING))) {
16972                                 ds = data_string_init();
16973                         }
16974  
16975                         buffer_copy_string_len(ds->value, start, end-start+1);
16976                         array_insert_unique(vals, (data_unset *)ds);
16977 -                       
16978 +
16979                         if (*s == ',') {
16980                                 state = 0;
16981                                 i++;
16982                                 s++;
16983                         } else {
16984                                 /* end of string */
16985 -                               
16986 +
16987                                 state = 2;
16988                         }
16989                         break;
16990 @@ -263,7 +265,7 @@
16991         if (c <= 32) return 0;
16992         if (c == 127) return 0;
16993         if (c == 255) return 0;
16994 -       
16995 +
16996         return 1;
16997  }
16998  
16999 @@ -271,28 +273,28 @@
17000         char *uri = NULL, *proto = NULL, *method = NULL, con_length_set;
17001         int is_key = 1, key_len = 0, is_ws_after_key = 0, in_folding;
17002         char *value = NULL, *key = NULL;
17003 -       
17004 +
17005         enum { HTTP_CONNECTION_UNSET, HTTP_CONNECTION_KEEPALIVE, HTTP_CONNECTION_CLOSE } keep_alive_set = HTTP_CONNECTION_UNSET;
17006 -       
17007 +
17008         int line = 0;
17009 -       
17010 +
17011         int request_line_stage = 0;
17012         size_t i, first;
17013 -       
17014 +
17015         int done = 0;
17016 -       
17017 +
17018         data_string *ds = NULL;
17019 -       
17020 -       /* 
17021 -        * Request: "^(GET|POST|HEAD) ([^ ]+(\\?[^ ]+|)) (HTTP/1\\.[01])$" 
17022 -        * Option : "^([-a-zA-Z]+): (.+)$"                    
17023 +
17024 +       /*
17025 +        * Request: "^(GET|POST|HEAD) ([^ ]+(\\?[^ ]+|)) (HTTP/1\\.[01])$"
17026 +        * Option : "^([-a-zA-Z]+): (.+)$"
17027          * End    : "^$"
17028          */
17029  
17030         if (con->conf.log_request_header) {
17031 -               log_error_write(srv, __FILE__, __LINE__, "sdsdSb", 
17032 -                               "fd:", con->fd, 
17033 -                               "request-len:", con->request.request->used, 
17034 +               log_error_write(srv, __FILE__, __LINE__, "sdsdSb",
17035 +                               "fd:", con->fd,
17036 +                               "request-len:", con->request.request->used,
17037                                 "\n", con->request.request);
17038         }
17039  
17040 @@ -300,13 +302,13 @@
17041             con->request.request->ptr[0] == '\r' &&
17042             con->request.request->ptr[1] == '\n') {
17043                 /* we are in keep-alive and might get \r\n after a previous POST request.*/
17044 -               
17045 +
17046                 buffer_copy_string_len(con->parse_request, con->request.request->ptr + 2, con->request.request->used - 1 - 2);
17047         } else {
17048                 /* fill the local request buffer */
17049                 buffer_copy_string_buffer(con->parse_request, con->request.request);
17050         }
17051 -       
17052 +
17053         keep_alive_set = 0;
17054         con_length_set = 0;
17055  
17056 @@ -318,25 +320,25 @@
17057          * */
17058         for (i = 0, first = 0; i < con->parse_request->used && line == 0; i++) {
17059                 char *cur = con->parse_request->ptr + i;
17060 -               
17061 +
17062                 switch(*cur) {
17063 -               case '\r': 
17064 +               case '\r':
17065                         if (con->parse_request->ptr[i+1] == '\n') {
17066                                 http_method_t r;
17067                                 char *nuri = NULL;
17068                                 size_t j;
17069 -                               
17070 +
17071                                 /* \r\n -> \0\0 */
17072                                 con->parse_request->ptr[i] = '\0';
17073                                 con->parse_request->ptr[i+1] = '\0';
17074 -                               
17075 +
17076                                 buffer_copy_string_len(con->request.request_line, con->parse_request->ptr, i);
17077 -                               
17078 +
17079                                 if (request_line_stage != 2) {
17080                                         con->http_status = 400;
17081                                         con->response.keep_alive = 0;
17082                                         con->keep_alive = 0;
17083 -                                       
17084 +
17085                                         if (srv->srvconf.log_request_header_on_error) {
17086                                                 log_error_write(srv, __FILE__, __LINE__, "s", "incomplete request line -> 400");
17087                                                 log_error_write(srv, __FILE__, __LINE__, "Sb",
17088 @@ -345,36 +347,36 @@
17089                                         }
17090                                         return 0;
17091                                 }
17092 -                               
17093 +
17094                                 proto = con->parse_request->ptr + first;
17095 -                               
17096 +
17097                                 *(uri - 1) = '\0';
17098                                 *(proto - 1) = '\0';
17099 -                               
17100 +
17101                                 /* we got the first one :) */
17102                                 if (-1 == (r = get_http_method_key(method))) {
17103                                         con->http_status = 501;
17104                                         con->response.keep_alive = 0;
17105                                         con->keep_alive = 0;
17106 -                                       
17107 +
17108                                         if (srv->srvconf.log_request_header_on_error) {
17109                                                 log_error_write(srv, __FILE__, __LINE__, "s", "unknown http-method -> 501");
17110                                                 log_error_write(srv, __FILE__, __LINE__, "Sb",
17111                                                                 "request-header:\n",
17112                                                                 con->request.request);
17113                                         }
17114 -                               
17115 +
17116                                         return 0;
17117                                 }
17118 -                               
17119 +
17120                                 con->request.http_method = r;
17121 -                       
17122 -                               /* 
17123 +
17124 +                               /*
17125                                  * RFC2616 says:
17126                                  *
17127                                  * HTTP-Version   = "HTTP" "/" 1*DIGIT "." 1*DIGIT
17128                                  *
17129 -                                * */   
17130 +                                * */
17131                                 if (0 == strncmp(proto, "HTTP/", sizeof("HTTP/") - 1)) {
17132                                         char * major = proto + sizeof("HTTP/") - 1;
17133                                         char * minor = strchr(major, '.');
17134 @@ -413,10 +415,10 @@
17135                                         }
17136  
17137                                         if (major_num == 1 && minor_num == 1) {
17138 -                                               con->request.http_version = con->conf.allow_http11 ? HTTP_VERSION_1_1 : HTTP_VERSION_1_0;
17139 +                                               con->request.http_version = HTTP_VERSION_1_1;
17140                                         } else if (major_num == 1 && minor_num == 0) {
17141                                                 con->request.http_version = HTTP_VERSION_1_0;
17142 -                                       } else { 
17143 +                                       } else {
17144                                                 con->http_status = 505;
17145  
17146                                                 if (srv->srvconf.log_request_header_on_error) {
17147 @@ -439,30 +441,30 @@
17148                                         }
17149                                         return 0;
17150                                 }
17151 -                               
17152 +
17153                                 if (0 == strncmp(uri, "http://", 7) &&
17154                                     NULL != (nuri = strchr(uri + 7, '/'))) {
17155                                         /* ignore the host-part */
17156 -                                       
17157 +
17158                                         buffer_copy_string_len(con->request.uri, nuri, proto - nuri - 1);
17159                                 } else {
17160                                         /* everything looks good so far */
17161                                         buffer_copy_string_len(con->request.uri, uri, proto - uri - 1);
17162                                 }
17163 -                               
17164 +
17165                                 /* check uri for invalid characters */
17166                                 for (j = 0; j < con->request.uri->used - 1; j++) {
17167                                         if (!request_uri_is_valid_char(con->request.uri->ptr[j])) {
17168                                                 unsigned char buf[2];
17169                                                 con->http_status = 400;
17170                                                 con->keep_alive = 0;
17171 -                                               
17172 +
17173                                                 if (srv->srvconf.log_request_header_on_error) {
17174                                                         buf[0] = con->request.uri->ptr[j];
17175                                                         buf[1] = '\0';
17176 -                                       
17177 +
17178                                                         if (con->request.uri->ptr[j] > 32 &&
17179 -                                                           con->request.uri->ptr[j] != 127) {  
17180 +                                                           con->request.uri->ptr[j] != 127) {
17181                                                                 /* the character is printable -> print it */
17182                                                                 log_error_write(srv, __FILE__, __LINE__, "ss",
17183                                                                                 "invalid character in URI -> 400",
17184 @@ -473,20 +475,20 @@
17185                                                                                 "invalid character in URI -> 400",
17186                                                                                 con->request.uri->ptr[j]);
17187                                                         }
17188 -                                               
17189 +
17190                                                         log_error_write(srv, __FILE__, __LINE__, "Sb",
17191                                                                         "request-header:\n",
17192                                                                         con->request.request);
17193                                                 }
17194 -                                               
17195 +
17196                                                 return 0;
17197                                         }
17198                                 }
17199 -                               
17200 +
17201                                 buffer_copy_string_buffer(con->request.orig_uri, con->request.uri);
17202 -                               
17203 +
17204                                 con->http_status = 0;
17205 -                               
17206 +
17207                                 i++;
17208                                 line++;
17209                                 first = i+1;
17210 @@ -494,14 +496,14 @@
17211                         break;
17212                 case ' ':
17213                         switch(request_line_stage) {
17214 -                       case 0: 
17215 +                       case 0:
17216                                 /* GET|POST|... */
17217 -                               method = con->parse_request->ptr + first; 
17218 +                               method = con->parse_request->ptr + first;
17219                                 first = i + 1;
17220                                 break;
17221                         case 1:
17222                                 /* /foobar/... */
17223 -                               uri = con->parse_request->ptr + first; 
17224 +                               uri = con->parse_request->ptr + first;
17225                                 first = i + 1;
17226                                 break;
17227                         default:
17228 @@ -509,7 +511,7 @@
17229                                 con->http_status = 400;
17230                                 con->response.keep_alive = 0;
17231                                 con->keep_alive = 0;
17232 -                               
17233 +
17234                                 if (srv->srvconf.log_request_header_on_error) {
17235                                         log_error_write(srv, __FILE__, __LINE__, "s", "overlong request line -> 400");
17236                                         log_error_write(srv, __FILE__, __LINE__, "Sb",
17237 @@ -518,12 +520,12 @@
17238                                 }
17239                                 return 0;
17240                         }
17241 -                       
17242 +
17243                         request_line_stage++;
17244                         break;
17245                 }
17246         }
17247 -       
17248 +
17249         in_folding = 0;
17250  
17251         if (con->request.uri->used == 1) {
17252 @@ -540,30 +542,30 @@
17253                 return 0;
17254         }
17255  
17256 -       
17257 +
17258         for (; i < con->parse_request->used && !done; i++) {
17259                 char *cur = con->parse_request->ptr + i;
17260 -               
17261 +
17262                 if (is_key) {
17263                         size_t j;
17264                         int got_colon = 0;
17265 -                       
17266 +
17267                         /**
17268                          * 1*<any CHAR except CTLs or separators>
17269                          * CTLs == 0-31 + 127
17270 -                        * 
17271 +                        *
17272                          */
17273                         switch(*cur) {
17274                         case ':':
17275                                 is_key = 0;
17276 -                               
17277 +
17278                                 value = cur + 1;
17279 -                               
17280 +
17281                                 if (is_ws_after_key == 0) {
17282                                         key_len = i - first;
17283                                 }
17284                                 is_ws_after_key = 0;
17285 -                                       
17286 +
17287                                 break;
17288                         case '(':
17289                         case ')':
17290 @@ -584,8 +586,8 @@
17291                                 con->http_status = 400;
17292                                 con->keep_alive = 0;
17293                                 con->response.keep_alive = 0;
17294 -                               
17295 -                               log_error_write(srv, __FILE__, __LINE__, "sbsds", 
17296 +
17297 +                               log_error_write(srv, __FILE__, __LINE__, "sbsds",
17298                                                 "invalid character in key", con->request.request, cur, *cur, "-> 400");
17299                                 return 0;
17300                         case ' ':
17301 @@ -594,13 +596,13 @@
17302                                         is_key = 0;
17303                                         in_folding = 1;
17304                                         value = cur;
17305 -                                       
17306 +
17307                                         break;
17308                                 }
17309 -                               
17310 -                               
17311 +
17312 +
17313                                 key_len = i - first;
17314 -                               
17315 +
17316                                 /* skip every thing up to the : */
17317                                 for (j = 1; !got_colon; j++) {
17318                                         switch(con->parse_request->ptr[j + i]) {
17319 @@ -610,40 +612,40 @@
17320                                                 continue;
17321                                         case ':':
17322                                                 /* ok, done */
17323 -                                               
17324 +
17325                                                 i += j - 1;
17326                                                 got_colon = 1;
17327 -                                               
17328 +
17329                                                 break;
17330                                         default:
17331                                                 /* error */
17332 -                                               
17333 +
17334                                                 if (srv->srvconf.log_request_header_on_error) {
17335                                                         log_error_write(srv, __FILE__, __LINE__, "s", "WS character in key -> 400");
17336                                                         log_error_write(srv, __FILE__, __LINE__, "Sb",
17337                                                                 "request-header:\n",
17338                                                                 con->request.request);
17339                                                 }
17340 -                                       
17341 +
17342                                                 con->http_status = 400;
17343                                                 con->response.keep_alive = 0;
17344                                                 con->keep_alive = 0;
17345 -                                               
17346 +
17347                                                 return 0;
17348                                         }
17349                                 }
17350 -                               
17351 +
17352                                 break;
17353                         case '\r':
17354                                 if (con->parse_request->ptr[i+1] == '\n' && i == first) {
17355                                         /* End of Header */
17356                                         con->parse_request->ptr[i] = '\0';
17357                                         con->parse_request->ptr[i+1] = '\0';
17358 -                                       
17359 +
17360                                         i++;
17361 -                                       
17362 +
17363                                         done = 1;
17364 -                                       
17365 +
17366                                         break;
17367                                 } else {
17368                                         if (srv->srvconf.log_request_header_on_error) {
17369 @@ -652,7 +654,7 @@
17370                                                         "request-header:\n",
17371                                                         con->request.request);
17372                                         }
17373 -                                       
17374 +
17375                                         con->http_status = 400;
17376                                         con->keep_alive = 0;
17377                                         con->response.keep_alive = 0;
17378 @@ -693,16 +695,16 @@
17379                                 con->http_status = 400;
17380                                 con->keep_alive = 0;
17381                                 con->response.keep_alive = 0;
17382 -                               
17383 +
17384                                 if (srv->srvconf.log_request_header_on_error) {
17385 -                                       log_error_write(srv, __FILE__, __LINE__, "sbsds", 
17386 +                                       log_error_write(srv, __FILE__, __LINE__, "sbsds",
17387                                                 "CTL character in key", con->request.request, cur, *cur, "-> 400");
17388  
17389                                         log_error_write(srv, __FILE__, __LINE__, "Sb",
17390                                                 "request-header:\n",
17391                                                 con->request.request);
17392                                 }
17393 -                               
17394 +
17395                                 return 0;
17396                         default:
17397                                 /* ok */
17398 @@ -710,25 +712,25 @@
17399                         }
17400                 } else {
17401                         switch(*cur) {
17402 -                       case '\r': 
17403 +                       case '\r':
17404                                 if (con->parse_request->ptr[i+1] == '\n') {
17405                                         /* End of Headerline */
17406                                         con->parse_request->ptr[i] = '\0';
17407                                         con->parse_request->ptr[i+1] = '\0';
17408 -                                       
17409 +
17410                                         if (in_folding) {
17411                                                 if (!ds) {
17412                                                         /* 400 */
17413 -                                       
17414 +
17415                                                         if (srv->srvconf.log_request_header_on_error) {
17416                                                                 log_error_write(srv, __FILE__, __LINE__, "s", "WS at the start of first line -> 400");
17417 -                                                       
17418 +
17419                                                                 log_error_write(srv, __FILE__, __LINE__, "Sb",
17420                                                                         "request-header:\n",
17421                                                                         con->request.request);
17422                                                         }
17423  
17424 -                                       
17425 +
17426                                                         con->http_status = 400;
17427                                                         con->keep_alive = 0;
17428                                                         con->response.keep_alive = 0;
17429 @@ -738,9 +740,9 @@
17430                                         } else {
17431                                                 int s_len;
17432                                                 key = con->parse_request->ptr + first;
17433 -                                       
17434 +
17435                                                 s_len = cur - value;
17436 -                                               
17437 +
17438                                                 if (s_len > 0) {
17439                                                         int cmp = 0;
17440                                                         if (NULL == (ds = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
17441 @@ -748,86 +750,87 @@
17442                                                         }
17443                                                         buffer_copy_string_len(ds->key, key, key_len);
17444                                                         buffer_copy_string_len(ds->value, value, s_len);
17445 -                                                       
17446 -                                                       /* retreive values 
17447 -                                                        * 
17448 -                                                        * 
17449 +
17450 +                                                       /* retreive values
17451 +                                                        *
17452 +                                                        *
17453                                                          * the list of options is sorted to simplify the search
17454                                                          */
17455 -                                                       
17456 +
17457                                                         if (0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Connection")))) {
17458                                                                 array *vals;
17459                                                                 size_t vi;
17460 -                                                               
17461 +
17462                                                                 /* split on , */
17463 -                                                               
17464 +
17465                                                                 vals = srv->split_vals;
17466  
17467                                                                 array_reset(vals);
17468 -                                                               
17469 +
17470                                                                 http_request_split_value(vals, ds->value);
17471 -                                                               
17472 +
17473                                                                 for (vi = 0; vi < vals->used; vi++) {
17474                                                                         data_string *dsv = (data_string *)vals->data[vi];
17475 -                                                                       
17476 +
17477                                                                         if (0 == buffer_caseless_compare(CONST_BUF_LEN(dsv->value), CONST_STR_LEN("keep-alive"))) {
17478                                                                                 keep_alive_set = HTTP_CONNECTION_KEEPALIVE;
17479 -                                                                               
17480 +
17481                                                                                 break;
17482                                                                         } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(dsv->value), CONST_STR_LEN("close"))) {
17483                                                                                 keep_alive_set = HTTP_CONNECTION_CLOSE;
17484 -                                                                               
17485 +
17486                                                                                 break;
17487                                                                         }
17488                                                                 }
17489 -                                                               
17490 +
17491                                                         } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Content-Length")))) {
17492                                                                 char *err;
17493                                                                 unsigned long int r;
17494                                                                 size_t j;
17495 -                                                               
17496 +
17497                                                                 if (con_length_set) {
17498                                                                         con->http_status = 400;
17499                                                                         con->keep_alive = 0;
17500 -                                                                       
17501 +
17502                                                                         if (srv->srvconf.log_request_header_on_error) {
17503 -                                                                               log_error_write(srv, __FILE__, __LINE__, "s", 
17504 +                                                                               log_error_write(srv, __FILE__, __LINE__, "s",
17505                                                                                                 "duplicate Content-Length-header -> 400");
17506                                                                                 log_error_write(srv, __FILE__, __LINE__, "Sb",
17507                                                                                                 "request-header:\n",
17508                                                                                                 con->request.request);
17509                                                                         }
17510 +                                                                       ds->free((data_unset *) ds);
17511                                                                         return 0;
17512                                                                 }
17513 -                                                               
17514 +
17515                                                                 if (ds->value->used == 0) SEGFAULT();
17516 -                                                               
17517 +
17518                                                                 for (j = 0; j < ds->value->used - 1; j++) {
17519                                                                         char c = ds->value->ptr[j];
17520                                                                         if (!isdigit((unsigned char)c)) {
17521 -                                                                               log_error_write(srv, __FILE__, __LINE__, "sbs", 
17522 +                                                                               log_error_write(srv, __FILE__, __LINE__, "sbs",
17523                                                                                                 "content-length broken:", ds->value, "-> 400");
17524 -                                                                               
17525 +
17526                                                                                 con->http_status = 400;
17527                                                                                 con->keep_alive = 0;
17528 -                                                                               
17529 +
17530                                                                                 array_insert_unique(con->request.headers, (data_unset *)ds);
17531                                                                                 return 0;
17532                                                                         }
17533                                                                 }
17534 -                                                               
17535 +
17536                                                                 r = strtoul(ds->value->ptr, &err, 10);
17537 -                                                               
17538 +
17539                                                                 if (*err == '\0') {
17540                                                                         con_length_set = 1;
17541                                                                         con->request.content_length = r;
17542                                                                 } else {
17543 -                                                                       log_error_write(srv, __FILE__, __LINE__, "sbs", 
17544 +                                                                       log_error_write(srv, __FILE__, __LINE__, "sbs",
17545                                                                                         "content-length broken:", ds->value, "-> 400");
17546 -                                                                       
17547 +
17548                                                                         con->http_status = 400;
17549                                                                         con->keep_alive = 0;
17550 -                                                                       
17551 +
17552                                                                         array_insert_unique(con->request.headers, (data_unset *)ds);
17553                                                                         return 0;
17554                                                                 }
17555 @@ -838,23 +841,24 @@
17556                                                                 } else {
17557                                                                         con->http_status = 400;
17558                                                                         con->keep_alive = 0;
17559 -                                                                       
17560 +
17561                                                                         if (srv->srvconf.log_request_header_on_error) {
17562 -                                                                               log_error_write(srv, __FILE__, __LINE__, "s", 
17563 +                                                                               log_error_write(srv, __FILE__, __LINE__, "s",
17564                                                                                                 "duplicate Content-Type-header -> 400");
17565                                                                                 log_error_write(srv, __FILE__, __LINE__, "Sb",
17566                                                                                                 "request-header:\n",
17567                                                                                                 con->request.request);
17568                                                                         }
17569 +                                                                       ds->free((data_unset *) ds);
17570                                                                         return 0;
17571                                                                 }
17572                                                         } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Expect")))) {
17573 -                                                               /* HTTP 2616 8.2.3 
17574 +                                                               /* HTTP 2616 8.2.3
17575                                                                  * Expect: 100-continue
17576 -                                                                * 
17577 +                                                                *
17578                                                                  *   -> (10.1.1)  100 (read content, process request, send final status-code)
17579                                                                  *   -> (10.4.18) 417 (close)
17580 -                                                                * 
17581 +                                                                *
17582                                                                  * (not handled at all yet, we always send 417 here)
17583                                                                  *
17584                                                                  * What has to be added ?
17585 @@ -863,10 +867,10 @@
17586                                                                  *    header
17587                                                                  *
17588                                                                  */
17589 -                                                               
17590 +
17591                                                                 con->http_status = 417;
17592                                                                 con->keep_alive = 0;
17593 -                                                               
17594 +
17595                                                                 array_insert_unique(con->request.headers, (data_unset *)ds);
17596                                                                 return 0;
17597                                                         } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Host")))) {
17598 @@ -875,14 +879,15 @@
17599                                                                 } else {
17600                                                                         con->http_status = 400;
17601                                                                         con->keep_alive = 0;
17602 -                                                                       
17603 +
17604                                                                         if (srv->srvconf.log_request_header_on_error) {
17605 -                                                                               log_error_write(srv, __FILE__, __LINE__, "s", 
17606 +                                                                               log_error_write(srv, __FILE__, __LINE__, "s",
17607                                                                                                 "duplicate Host-header -> 400");
17608                                                                                 log_error_write(srv, __FILE__, __LINE__, "Sb",
17609                                                                                                 "request-header:\n",
17610                                                                                                 con->request.request);
17611                                                                         }
17612 +                                                                       ds->free((data_unset *) ds);
17613                                                                         return 0;
17614                                                                 }
17615                                                         } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("If-Modified-Since")))) {
17616 @@ -897,14 +902,15 @@
17617                                                                 } else {
17618                                                                         con->http_status = 400;
17619                                                                         con->keep_alive = 0;
17620 -                                                                       
17621 +
17622                                                                         if (srv->srvconf.log_request_header_on_error) {
17623 -                                                                               log_error_write(srv, __FILE__, __LINE__, "s", 
17624 +                                                                               log_error_write(srv, __FILE__, __LINE__, "s",
17625                                                                                                 "duplicate If-Modified-Since header -> 400");
17626                                                                                 log_error_write(srv, __FILE__, __LINE__, "Sb",
17627                                                                                                 "request-header:\n",
17628                                                                                                 con->request.request);
17629                                                                         }
17630 +                                                                       ds->free((data_unset *) ds);
17631                                                                         return 0;
17632                                                                 }
17633                                                         } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("If-None-Match")))) {
17634 @@ -914,47 +920,49 @@
17635                                                                 } else {
17636                                                                         con->http_status = 400;
17637                                                                         con->keep_alive = 0;
17638 -                                                                       
17639 +
17640                                                                         if (srv->srvconf.log_request_header_on_error) {
17641 -                                                                               log_error_write(srv, __FILE__, __LINE__, "s", 
17642 +                                                                               log_error_write(srv, __FILE__, __LINE__, "s",
17643                                                                                                 "duplicate If-None-Match-header -> 400");
17644                                                                                 log_error_write(srv, __FILE__, __LINE__, "Sb",
17645                                                                                                 "request-header:\n",
17646                                                                                                 con->request.request);
17647                                                                         }
17648 +                                                                       ds->free((data_unset *) ds);
17649                                                                         return 0;
17650                                                                 }
17651                                                         } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Range")))) {
17652                                                                 if (!con->request.http_range) {
17653                                                                         /* bytes=.*-.* */
17654 -                                                               
17655 +
17656                                                                         if (0 == strncasecmp(ds->value->ptr, "bytes=", 6) &&
17657                                                                             NULL != strchr(ds->value->ptr+6, '-')) {
17658 -                                                                               
17659 +
17660                                                                                 /* if dup, only the first one will survive */
17661                                                                                 con->request.http_range = ds->value->ptr + 6;
17662                                                                         }
17663                                                                 } else {
17664                                                                         con->http_status = 400;
17665                                                                         con->keep_alive = 0;
17666 -                                                                       
17667 +
17668                                                                         if (srv->srvconf.log_request_header_on_error) {
17669 -                                                                               log_error_write(srv, __FILE__, __LINE__, "s", 
17670 +                                                                               log_error_write(srv, __FILE__, __LINE__, "s",
17671                                                                                                 "duplicate Range-header -> 400");
17672                                                                                 log_error_write(srv, __FILE__, __LINE__, "Sb",
17673                                                                                                 "request-header:\n",
17674                                                                                                 con->request.request);
17675                                                                         }
17676 +                                                                       ds->free((data_unset *) ds);
17677                                                                         return 0;
17678                                                                 }
17679                                                         }
17680 -                                                       
17681 +
17682                                                         array_insert_unique(con->request.headers, (data_unset *)ds);
17683                                                 } else {
17684                                                         /* empty header-fields are not allowed by HTTP-RFC, we just ignore them */
17685                                                 }
17686                                         }
17687 -                                       
17688 +
17689                                         i++;
17690                                         first = i+1;
17691                                         is_key = 1;
17692 @@ -963,10 +971,10 @@
17693                                         in_folding = 0;
17694                                 } else {
17695                                         if (srv->srvconf.log_request_header_on_error) {
17696 -                                               log_error_write(srv, __FILE__, __LINE__, "sbs", 
17697 +                                               log_error_write(srv, __FILE__, __LINE__, "sbs",
17698                                                                 "CR without LF", con->request.request, "-> 400");
17699                                         }
17700 -                                       
17701 +
17702                                         con->http_status = 400;
17703                                         con->keep_alive = 0;
17704                                         con->response.keep_alive = 0;
17705 @@ -982,28 +990,28 @@
17706                         }
17707                 }
17708         }
17709 -       
17710 +
17711         con->header_len = i;
17712 -       
17713 +
17714         /* do some post-processing */
17715  
17716         if (con->request.http_version == HTTP_VERSION_1_1) {
17717                 if (keep_alive_set != HTTP_CONNECTION_CLOSE) {
17718                         /* no Connection-Header sent */
17719 -                       
17720 +
17721                         /* HTTP/1.1 -> keep-alive default TRUE */
17722                         con->keep_alive = 1;
17723                 } else {
17724                         con->keep_alive = 0;
17725                 }
17726 -               
17727 +
17728                 /* RFC 2616, 14.23 */
17729                 if (con->request.http_host == NULL ||
17730                     buffer_is_empty(con->request.http_host)) {
17731                         con->http_status = 400;
17732                         con->response.keep_alive = 0;
17733                         con->keep_alive = 0;
17734 -                       
17735 +
17736                         if (srv->srvconf.log_request_header_on_error) {
17737                                 log_error_write(srv, __FILE__, __LINE__, "s", "HTTP/1.1 but Host missing -> 400");
17738                                 log_error_write(srv, __FILE__, __LINE__, "Sb",
17739 @@ -1015,18 +1023,18 @@
17740         } else {
17741                 if (keep_alive_set == HTTP_CONNECTION_KEEPALIVE) {
17742                         /* no Connection-Header sent */
17743 -                       
17744 +
17745                         /* HTTP/1.0 -> keep-alive default FALSE  */
17746                         con->keep_alive = 1;
17747                 } else {
17748                         con->keep_alive = 0;
17749                 }
17750         }
17751 -       
17752 +
17753         /* check hostname field if it is set */
17754         if (NULL != con->request.http_host &&
17755             0 != request_check_hostname(srv, con, con->request.http_host)) {
17756 -               
17757 +
17758                 if (srv->srvconf.log_request_header_on_error) {
17759                         log_error_write(srv, __FILE__, __LINE__, "s",
17760                                         "Invalid Hostname -> 400");
17761 @@ -1038,7 +1046,7 @@
17762                 con->http_status = 400;
17763                 con->response.keep_alive = 0;
17764                 con->keep_alive = 0;
17765 -               
17766 +
17767                 return 0;
17768         }
17769  
17770 @@ -1048,7 +1056,7 @@
17771                 /* content-length is forbidden for those */
17772                 if (con_length_set && con->request.content_length != 0) {
17773                         /* content-length is missing */
17774 -                       log_error_write(srv, __FILE__, __LINE__, "s", 
17775 +                       log_error_write(srv, __FILE__, __LINE__, "s",
17776                                         "GET/HEAD with content-length -> 400");
17777  
17778                         con->keep_alive = 0;
17779 @@ -1060,7 +1068,7 @@
17780                 /* content-length is required for them */
17781                 if (!con_length_set) {
17782                         /* content-length is missing */
17783 -                       log_error_write(srv, __FILE__, __LINE__, "s", 
17784 +                       log_error_write(srv, __FILE__, __LINE__, "s",
17785                                         "POST-request, but content-length missing -> 411");
17786  
17787                         con->keep_alive = 0;
17788 @@ -1073,16 +1081,16 @@
17789                 /* the may have a content-length */
17790                 break;
17791         }
17792 -                       
17793 -       
17794 +
17795 +
17796         /* check if we have read post data */
17797         if (con_length_set) {
17798                 /* don't handle more the SSIZE_MAX bytes in content-length */
17799                 if (con->request.content_length > SSIZE_MAX) {
17800 -                       con->http_status = 413; 
17801 +                       con->http_status = 413;
17802                         con->keep_alive = 0;
17803  
17804 -                       log_error_write(srv, __FILE__, __LINE__, "sds", 
17805 +                       log_error_write(srv, __FILE__, __LINE__, "sds",
17806                                         "request-size too long:", con->request.content_length, "-> 413");
17807                         return 0;
17808                 }
17809 @@ -1090,25 +1098,25 @@
17810                 /* divide by 1024 as srvconf.max_request_size is in kBytes */
17811                 if (srv->srvconf.max_request_size != 0 &&
17812                     (con->request.content_length >> 10) > srv->srvconf.max_request_size) {
17813 -                       /* the request body itself is larger then 
17814 +                       /* the request body itself is larger then
17815                          * our our max_request_size
17816                          */
17817 -               
17818 +
17819                         con->http_status = 413;
17820                         con->keep_alive = 0;
17821 -               
17822 -                       log_error_write(srv, __FILE__, __LINE__, "sds", 
17823 +
17824 +                       log_error_write(srv, __FILE__, __LINE__, "sds",
17825                                         "request-size too long:", con->request.content_length, "-> 413");
17826                         return 0;
17827                 }
17828 -               
17829 -               
17830 +
17831 +
17832                 /* we have content */
17833                 if (con->request.content_length != 0) {
17834                         return 1;
17835                 }
17836         }
17837 -       
17838 +
17839         return 0;
17840  }
17841  
17842 @@ -1116,9 +1124,9 @@
17843         UNUSED(srv);
17844  
17845         if (con->request.request->used < 5) return 0;
17846 -       
17847 +
17848         if (0 == memcmp(con->request.request->ptr + con->request.request->used - 5, "\r\n\r\n", 4)) return 1;
17849         if (NULL != strstr(con->request.request->ptr, "\r\n\r\n")) return 1;
17850 -       
17851 +
17852         return 0;
17853  }
17854
17855 Property changes on: src/request.c
17856 ___________________________________________________________________
17857 Name: svn:eol-style
17858    + native
17859
17860 Index: src/network_backends.h
17861 ===================================================================
17862 --- src/network_backends.h      (.../tags/lighttpd-1.4.11)      (revision 1159)
17863 +++ src/network_backends.h      (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
17864 @@ -43,16 +43,52 @@
17865  # define USE_AIX_SENDFILE
17866  #endif
17867  
17868 +/**
17869 +* unix can use read/write or recv/send on sockets
17870 +* win32 only recv/send
17871 +*/
17872 +#ifdef _WIN32
17873 +# define USE_WIN32_SEND
17874 +/* wait for async-io support
17875 +# define USE_WIN32_TRANSMITFILE
17876 +*/
17877 +#else
17878 +# define USE_WRITE
17879 +#endif
17880 +
17881  #include "base.h"
17882 +#include "network.h"
17883  
17884 +#define NETWORK_BACKEND_WRITE_CHUNK(x) \
17885 +    network_status_t network_write_chunkqueue_##x(server *srv, connection *con, int fd, chunkqueue *cq, chunk *c)
17886  
17887 -int network_write_chunkqueue_write(server *srv, connection *con, int fd, chunkqueue *cq);
17888 -int network_write_chunkqueue_writev(server *srv, connection *con, int fd, chunkqueue *cq);
17889 -int network_write_chunkqueue_linuxsendfile(server *srv, connection *con, int fd, chunkqueue *cq);
17890 -int network_write_chunkqueue_freebsdsendfile(server *srv, connection *con, int fd, chunkqueue *cq);
17891 -int network_write_chunkqueue_solarissendfilev(server *srv, connection *con, int fd, chunkqueue *cq);
17892 +#define NETWORK_BACKEND_WRITE(x) \
17893 +    network_status_t network_write_chunkqueue_##x(server *srv, connection *con, int fd, chunkqueue *cq)
17894 +#define NETWORK_BACKEND_READ(x) \
17895 +    network_status_t network_read_chunkqueue_##x(server *srv, connection *con, int fd, chunkqueue *cq)
17896 +
17897 +NETWORK_BACKEND_WRITE_CHUNK(writev_mem);
17898 +
17899 +NETWORK_BACKEND_WRITE(write);
17900 +NETWORK_BACKEND_WRITE(writev);
17901 +NETWORK_BACKEND_WRITE(linuxsendfile);
17902 +NETWORK_BACKEND_WRITE(freebsdsendfile);
17903 +NETWORK_BACKEND_WRITE(solarissendfilev);
17904 +
17905 +NETWORK_BACKEND_WRITE(win32transmitfile);
17906 +NETWORK_BACKEND_WRITE(win32send);
17907 +
17908 +NETWORK_BACKEND_READ(read);
17909 +NETWORK_BACKEND_READ(win32recv);
17910 +
17911  #ifdef USE_OPENSSL
17912 -int network_write_chunkqueue_openssl(server *srv, connection *con, SSL *ssl, chunkqueue *cq);
17913 +#define NETWORK_BACKEND_WRITE_SSL(x) \
17914 +    network_status_t network_write_chunkqueue_##x(server *srv, connection *con, SSL *ssl, chunkqueue *cq)
17915 +#define NETWORK_BACKEND_READ_SSL(x) \
17916 +    network_status_t network_read_chunkqueue_##x(server *srv, connection *con, SSL *ssl, chunkqueue *cq)
17917 +
17918 +NETWORK_BACKEND_WRITE_SSL(openssl);
17919 +NETWORK_BACKEND_READ_SSL(openssl);
17920  #endif
17921  
17922  #endif
17923
17924 Property changes on: src/network_backends.h
17925 ___________________________________________________________________
17926 Name: svn:eol-style
17927    + native
17928
17929
17930 Property changes on: src/bitset.c
17931 ___________________________________________________________________
17932 Name: svn:eol-style
17933    + native
17934
17935 Index: src/keyvalue.h
17936 ===================================================================
17937 --- src/keyvalue.h      (.../tags/lighttpd-1.4.11)      (revision 1159)
17938 +++ src/keyvalue.h      (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
17939 @@ -9,19 +9,19 @@
17940  # include <pcre.h>
17941  #endif
17942  
17943 -typedef enum { 
17944 -       HTTP_METHOD_UNSET = -1, 
17945 -       HTTP_METHOD_GET, 
17946 -       HTTP_METHOD_POST, 
17947 -       HTTP_METHOD_HEAD, 
17948 -       HTTP_METHOD_OPTIONS, 
17949 +typedef enum {
17950 +       HTTP_METHOD_UNSET = -1,
17951 +       HTTP_METHOD_GET,
17952 +       HTTP_METHOD_POST,
17953 +       HTTP_METHOD_HEAD,
17954 +       HTTP_METHOD_OPTIONS,
17955         HTTP_METHOD_PROPFIND,  /* WebDAV */
17956 -       HTTP_METHOD_MKCOL, 
17957 -       HTTP_METHOD_PUT, 
17958 -       HTTP_METHOD_DELETE, 
17959 -       HTTP_METHOD_COPY, 
17960 -       HTTP_METHOD_MOVE, 
17961 -       HTTP_METHOD_PROPPATCH, 
17962 +       HTTP_METHOD_MKCOL,
17963 +       HTTP_METHOD_PUT,
17964 +       HTTP_METHOD_DELETE,
17965 +       HTTP_METHOD_COPY,
17966 +       HTTP_METHOD_MOVE,
17967 +       HTTP_METHOD_PROPPATCH,
17968         HTTP_METHOD_REPORT, /* DeltaV */
17969         HTTP_METHOD_CHECKOUT,
17970         HTTP_METHOD_CHECKIN,
17971 @@ -39,13 +39,13 @@
17972  
17973  typedef struct {
17974         int key;
17975 -       
17976 +
17977         char *value;
17978  } keyvalue;
17979  
17980  typedef struct {
17981         char *key;
17982 -       
17983 +
17984         char *value;
17985  } s_keyvalue;
17986  
17987 @@ -54,7 +54,7 @@
17988         pcre *key;
17989         pcre_extra *key_extra;
17990  #endif
17991 -       
17992 +
17993         buffer *value;
17994  } pcre_keyvalue;
17995  
17996 @@ -62,7 +62,7 @@
17997  
17998  typedef struct {
17999         char *key;
18000 -       
18001 +
18002         char *realm;
18003         httpauth_type type;
18004  } httpauth_keyvalue;
18005
18006 Property changes on: src/keyvalue.h
18007 ___________________________________________________________________
18008 Name: svn:eol-style
18009    + native
18010
18011
18012 Property changes on: src/request.h
18013 ___________________________________________________________________
18014 Name: svn:eol-style
18015    + native
18016
18017 Index: src/mod_flv_streaming.c
18018 ===================================================================
18019 --- src/mod_flv_streaming.c     (.../tags/lighttpd-1.4.11)      (revision 1159)
18020 +++ src/mod_flv_streaming.c     (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
18021 @@ -23,35 +23,35 @@
18022  
18023  typedef struct {
18024         PLUGIN_DATA;
18025 -       
18026 +
18027         buffer *query_str;
18028         array *get_params;
18029 -       
18030 +
18031         plugin_config **config_storage;
18032 -       
18033 -       plugin_config conf; 
18034 +
18035 +       plugin_config conf;
18036  } plugin_data;
18037  
18038  /* init the plugin data */
18039  INIT_FUNC(mod_flv_streaming_init) {
18040         plugin_data *p;
18041 -       
18042 +
18043         p = calloc(1, sizeof(*p));
18044 -       
18045 +
18046         p->query_str = buffer_init();
18047         p->get_params = array_init();
18048 -       
18049 +
18050         return p;
18051  }
18052  
18053  /* detroy the plugin data */
18054  FREE_FUNC(mod_flv_streaming_free) {
18055         plugin_data *p = p_d;
18056 -       
18057 +
18058         UNUSED(srv);
18059  
18060         if (!p) return HANDLER_GO_ON;
18061 -       
18062 +
18063         if (p->config_storage) {
18064                 size_t i;
18065  
18066 @@ -59,19 +59,19 @@
18067                         plugin_config *s = p->config_storage[i];
18068  
18069                         if (!s) continue;
18070 -                       
18071 +
18072                         array_free(s->extensions);
18073 -                       
18074 +
18075                         free(s);
18076                 }
18077                 free(p->config_storage);
18078         }
18079 -       
18080 +
18081         buffer_free(p->query_str);
18082         array_free(p->get_params);
18083 -       
18084 +
18085         free(p);
18086 -       
18087 +
18088         return HANDLER_GO_ON;
18089  }
18090  
18091 @@ -80,83 +80,80 @@
18092  SETDEFAULTS_FUNC(mod_flv_streaming_set_defaults) {
18093         plugin_data *p = p_d;
18094         size_t i = 0;
18095 -       
18096 -       config_values_t cv[] = { 
18097 +
18098 +       config_values_t cv[] = {
18099                 { "flv-streaming.extensions",   NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
18100                 { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
18101         };
18102 -       
18103 +
18104         if (!p) return HANDLER_ERROR;
18105 -       
18106 +
18107         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
18108 -       
18109 +
18110         for (i = 0; i < srv->config_context->used; i++) {
18111                 plugin_config *s;
18112 -               
18113 +
18114                 s = calloc(1, sizeof(plugin_config));
18115                 s->extensions     = array_init();
18116 -               
18117 +
18118                 cv[0].destination = s->extensions;
18119 -               
18120 +
18121                 p->config_storage[i] = s;
18122 -       
18123 +
18124                 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
18125                         return HANDLER_ERROR;
18126                 }
18127         }
18128 -       
18129 +
18130         return HANDLER_GO_ON;
18131  }
18132  
18133 -#define PATCH(x) \
18134 -       p->conf.x = s->x;
18135  static int mod_flv_streaming_patch_connection(server *srv, connection *con, plugin_data *p) {
18136         size_t i, j;
18137         plugin_config *s = p->config_storage[0];
18138 -       
18139 -       PATCH(extensions);
18140 -       
18141 +
18142 +       PATCH_OPTION(extensions);
18143 +
18144         /* skip the first, the global context */
18145         for (i = 1; i < srv->config_context->used; i++) {
18146                 data_config *dc = (data_config *)srv->config_context->data[i];
18147                 s = p->config_storage[i];
18148 -               
18149 +
18150                 /* condition didn't match */
18151                 if (!config_check_cond(srv, con, dc)) continue;
18152 -               
18153 +
18154                 /* merge config */
18155                 for (j = 0; j < dc->value->used; j++) {
18156                         data_unset *du = dc->value->data[j];
18157 -                       
18158 +
18159                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("flv-streaming.extensions"))) {
18160 -                               PATCH(extensions);
18161 +                               PATCH_OPTION(extensions);
18162                         }
18163                 }
18164         }
18165 -       
18166 +
18167         return 0;
18168  }
18169 -#undef PATCH
18170  
18171 -static int split_get_params(server *srv, connection *con, array *get_params, buffer *qrystr) {
18172 +static int split_get_params(array *get_params, buffer *qrystr) {
18173         size_t is_key = 1;
18174         size_t i;
18175         char *key = NULL, *val = NULL;
18176 -       
18177 +
18178         key = qrystr->ptr;
18179 -       
18180 +
18181         /* we need the \0 */
18182         for (i = 0; i < qrystr->used; i++) {
18183                 switch(qrystr->ptr[i]) {
18184                 case '=':
18185                         if (is_key) {
18186                                 val = qrystr->ptr + i + 1;
18187 -                               
18188 +
18189                                 qrystr->ptr[i] = '\0';
18190 -                               
18191 +
18192                                 is_key = 0;
18193                         }
18194 -                       
18195 +
18196                         break;
18197                 case '&':
18198                 case '\0': /* fin symbol */
18199 @@ -167,7 +164,7 @@
18200                                 /* terminate the value */
18201                                 qrystr->ptr[i] = '\0';
18202  
18203 -                               if (NULL == (ds = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
18204 +                               if (NULL == (ds = (data_string *)array_get_unused_element(get_params, TYPE_STRING))) {
18205                                         ds = data_string_init();
18206                                 }
18207                                 buffer_copy_string_len(ds->key, key, strlen(key));
18208 @@ -175,14 +172,14 @@
18209  
18210                                 array_insert_unique(get_params, (data_unset *)ds);
18211                         }
18212 -                       
18213 +
18214                         key = qrystr->ptr + i + 1;
18215                         val = NULL;
18216                         is_key = 1;
18217                         break;
18218                 }
18219         }
18220 -       
18221 +
18222         return 0;
18223  }
18224  
18225 @@ -190,34 +187,34 @@
18226         plugin_data *p = p_d;
18227         int s_len;
18228         size_t k;
18229 -       
18230 +
18231         UNUSED(srv);
18232  
18233         if (buffer_is_empty(con->physical.path)) return HANDLER_GO_ON;
18234 -       
18235 +
18236         mod_flv_streaming_patch_connection(srv, con, p);
18237  
18238         s_len = con->physical.path->used - 1;
18239 -       
18240 +
18241         for (k = 0; k < p->conf.extensions->used; k++) {
18242                 data_string *ds = (data_string *)p->conf.extensions->data[k];
18243                 int ct_len = ds->value->used - 1;
18244 -               
18245 +
18246                 if (ct_len > s_len) continue;
18247                 if (ds->value->used == 0) continue;
18248 -               
18249 +
18250                 if (0 == strncmp(con->physical.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) {
18251                         data_string *get_param;
18252                         stat_cache_entry *sce = NULL;
18253                         buffer *b;
18254                         int start;
18255                         char *err = NULL;
18256 -                       /* if there is a start=[0-9]+ in the header use it as start, 
18257 +                       /* if there is a start=[0-9]+ in the header use it as start,
18258                          * otherwise send the full file */
18259  
18260                         array_reset(p->get_params);
18261                         buffer_copy_string_buffer(p->query_str, con->uri.query);
18262 -                       split_get_params(srv, con, p->get_params, p->query_str);
18263 +                       split_get_params(p->get_params, p->query_str);
18264  
18265                         if (NULL == (get_param = (data_string *)array_get_element(p->get_params, "start"))) {
18266                                 return HANDLER_GO_ON;
18267 @@ -256,7 +253,7 @@
18268                         return HANDLER_FINISHED;
18269                 }
18270         }
18271 -       
18272 +
18273         /* not found */
18274         return HANDLER_GO_ON;
18275  }
18276 @@ -266,13 +263,13 @@
18277  int mod_flv_streaming_plugin_init(plugin *p) {
18278         p->version     = LIGHTTPD_VERSION_ID;
18279         p->name        = buffer_init_string("flv_streaming");
18280 -       
18281 +
18282         p->init        = mod_flv_streaming_init;
18283         p->handle_physical = mod_flv_streaming_path_handler;
18284         p->set_defaults  = mod_flv_streaming_set_defaults;
18285         p->cleanup     = mod_flv_streaming_free;
18286 -       
18287 +
18288         p->data        = NULL;
18289 -       
18290 +
18291         return 0;
18292  }
18293
18294 Property changes on: src/mod_flv_streaming.c
18295 ___________________________________________________________________
18296 Name: svn:eol-style
18297    + native
18298
18299
18300 Property changes on: src/bitset.h
18301 ___________________________________________________________________
18302 Name: svn:eol-style
18303    + native
18304
18305 Index: src/sys-socket.c
18306 ===================================================================
18307 --- src/sys-socket.c    (.../tags/lighttpd-1.4.11)      (revision 0)
18308 +++ src/sys-socket.c    (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
18309 @@ -0,0 +1,22 @@
18310 +#include "sys-socket.h"
18311 +
18312 +#ifndef HAVE_INET_ATON
18313 +/* win32 has inet_addr instead if inet_aton */
18314 +#ifdef HAVE_INET_ADDR
18315 +int inet_aton(const char *cp, struct in_addr *inp) {
18316 +    struct in_addr a;
18317 +
18318 +    a.s_addr = inet_addr(cp);
18319 +
18320 +    if (INADDR_NONE == a.s_addr) {
18321 +        return 0;
18322 +    }
18323 +
18324 +    inp->s_addr = a.s_addr;
18325 +
18326 +    return 1;
18327 +}
18328 +#else
18329 +#error no inet_aton emulation found
18330 +#endif
18331 +#endif
18332 \ No newline at end of file
18333
18334 Property changes on: src/sys-socket.c
18335 ___________________________________________________________________
18336 Name: svn:eol-style
18337    + native
18338
18339 Index: src/sys-socket.h
18340 ===================================================================
18341 --- src/sys-socket.h    (.../tags/lighttpd-1.4.11)      (revision 1159)
18342 +++ src/sys-socket.h    (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
18343 @@ -1,15 +1,26 @@
18344  #ifndef WIN32_SOCKET_H
18345  #define WIN32_SOCKET_H
18346  
18347 -#ifdef __WIN32
18348 +#ifdef _WIN32
18349  
18350  #include <winsock2.h>
18351  
18352  #define ECONNRESET WSAECONNRESET
18353  #define EINPROGRESS WSAEINPROGRESS
18354  #define EALREADY WSAEALREADY
18355 +#define ENOTCONN WSAENOTCONN
18356 +#define EWOULDBLOCK WSAEWOULDBLOCK
18357  #define ioctl ioctlsocket
18358  #define hstrerror(x) ""
18359 +#define STDIN_FILENO 0
18360 +#define STDOUT_FILENO 1
18361 +#define STDERR_FILENO 2
18362 +#define ssize_t int
18363 +
18364 +int inet_aton(const char *cp, struct in_addr *inp);
18365 +#define HAVE_INET_ADDR
18366 +#undef HAVE_INET_ATON
18367 +
18368  #else
18369  #include <sys/socket.h>
18370  #include <sys/ioctl.h>
18371 @@ -18,6 +29,11 @@
18372  #include <sys/un.h>
18373  #include <arpa/inet.h>
18374  
18375 +#ifndef SUN_LEN
18376 +#define SUN_LEN(su) \
18377 +        (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
18378 +#endif
18379 +
18380  #include <netdb.h>
18381  #endif
18382  
18383
18384 Property changes on: src/sys-socket.h
18385 ___________________________________________________________________
18386 Name: svn:eol-style
18387    + native
18388
18389 Index: src/sys-mmap.h
18390 ===================================================================
18391 --- src/sys-mmap.h      (.../tags/lighttpd-1.4.11)      (revision 1159)
18392 +++ src/sys-mmap.h      (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
18393 @@ -1,7 +1,7 @@
18394  #ifndef WIN32_MMAP_H
18395  #define WIN32_MMAP_H
18396  
18397 -#ifdef __WIN32
18398 +#ifdef _WIN32
18399  
18400  #define MAP_FAILED -1
18401  #define PROT_SHARED 0
18402
18403 Property changes on: src/sys-mmap.h
18404 ___________________________________________________________________
18405 Name: svn:eol-style
18406    + native
18407
18408 Index: src/inet_ntop_cache.c
18409 ===================================================================
18410 --- src/inet_ntop_cache.c       (.../tags/lighttpd-1.4.11)      (revision 1159)
18411 +++ src/inet_ntop_cache.c       (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
18412 @@ -8,7 +8,7 @@
18413  #include "sys-socket.h"
18414  
18415  const char * inet_ntop_cache_get_ip(server *srv, sock_addr *addr) {
18416 -#ifdef HAVE_IPV6       
18417 +#ifdef HAVE_IPV6
18418         size_t ndx = 0, i;
18419         for (i = 0; i < INET_NTOP_CACHE_MAX; i++) {
18420                 if (srv->inet_ntop_cache[i].ts != 0) {
18421 @@ -20,31 +20,31 @@
18422                                    srv->inet_ntop_cache[i].addr.ipv4.s_addr == addr->ipv4.sin_addr.s_addr) {
18423                                 /* IPv4 found in cache */
18424                                 break;
18425 -                               
18426 +
18427                         }
18428                 }
18429         }
18430 -       
18431 +
18432         if (i == INET_NTOP_CACHE_MAX) {
18433                 /* not found in cache */
18434 -               
18435 +
18436                 i = ndx;
18437 -               inet_ntop(addr->plain.sa_family, 
18438 -                         addr->plain.sa_family == AF_INET6 ? 
18439 +               inet_ntop(addr->plain.sa_family,
18440 +                         addr->plain.sa_family == AF_INET6 ?
18441                           (const void *) &(addr->ipv6.sin6_addr) :
18442                           (const void *) &(addr->ipv4.sin_addr),
18443                           srv->inet_ntop_cache[i].b2, INET6_ADDRSTRLEN);
18444 -               
18445 +
18446                 srv->inet_ntop_cache[i].ts = srv->cur_ts;
18447                 srv->inet_ntop_cache[i].family = addr->plain.sa_family;
18448 -               
18449 +
18450                 if (srv->inet_ntop_cache[i].family == AF_INET) {
18451                         srv->inet_ntop_cache[i].addr.ipv4.s_addr = addr->ipv4.sin_addr.s_addr;
18452                 } else if (srv->inet_ntop_cache[i].family == AF_INET6) {
18453                         memcpy(srv->inet_ntop_cache[i].addr.ipv6.s6_addr, addr->ipv6.sin6_addr.s6_addr, 16);
18454                 }
18455         }
18456 -       
18457 +
18458         return srv->inet_ntop_cache[i].b2;
18459  #else
18460         UNUSED(srv);
18461
18462 Property changes on: src/inet_ntop_cache.c
18463 ___________________________________________________________________
18464 Name: svn:eol-style
18465    + native
18466
18467 Index: src/mod_rrdtool.c
18468 ===================================================================
18469 --- src/mod_rrdtool.c   (.../tags/lighttpd-1.4.11)      (revision 1159)
18470 +++ src/mod_rrdtool.c   (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
18471 @@ -5,7 +5,6 @@
18472  #include <stdlib.h>
18473  #include <stdio.h>
18474  #include <string.h>
18475 -#include <unistd.h>
18476  #include <errno.h>
18477  #include <time.h>
18478  
18479 @@ -20,10 +19,14 @@
18480  /* no need for waitpid if we don't have fork */
18481  #include <sys/wait.h>
18482  #endif
18483 +
18484 +#include "sys-files.h"
18485 +#include "sys-process.h"
18486 +
18487  typedef struct {
18488         buffer *path_rrdtool_bin;
18489         buffer *path_rrd;
18490 -       
18491 +
18492         double requests, *requests_ptr;
18493         double bytes_written, *bytes_written_ptr;
18494         double bytes_read, *bytes_read_ptr;
18495 @@ -31,84 +34,84 @@
18496  
18497  typedef struct {
18498         PLUGIN_DATA;
18499 -       
18500 +
18501         buffer *cmd;
18502         buffer *resp;
18503 -       
18504 +
18505         int read_fd, write_fd;
18506         pid_t rrdtool_pid;
18507 -       
18508 +
18509         int rrdtool_running;
18510 -       
18511 +
18512         plugin_config **config_storage;
18513         plugin_config conf;
18514  } plugin_data;
18515  
18516  INIT_FUNC(mod_rrd_init) {
18517         plugin_data *p;
18518 -       
18519 +
18520         p = calloc(1, sizeof(*p));
18521 -       
18522 +
18523         p->resp = buffer_init();
18524         p->cmd = buffer_init();
18525 -       
18526 +
18527         return p;
18528  }
18529  
18530  FREE_FUNC(mod_rrd_free) {
18531         plugin_data *p = p_d;
18532         size_t i;
18533 -       
18534 +
18535         if (!p) return HANDLER_GO_ON;
18536 -       
18537 +
18538         if (p->config_storage) {
18539                 for (i = 0; i < srv->config_context->used; i++) {
18540                         plugin_config *s = p->config_storage[i];
18541 -                       
18542 +
18543                         buffer_free(s->path_rrdtool_bin);
18544                         buffer_free(s->path_rrd);
18545 -                       
18546 +
18547                         free(s);
18548                 }
18549         }
18550         buffer_free(p->cmd);
18551         buffer_free(p->resp);
18552 -       
18553 +
18554         free(p->config_storage);
18555 -       
18556 +
18557         if (p->rrdtool_pid) {
18558                 int status;
18559                 close(p->read_fd);
18560                 close(p->write_fd);
18561 -#ifdef HAVE_FORK       
18562 +#ifdef HAVE_FORK
18563                 /* collect status */
18564                 waitpid(p->rrdtool_pid, &status, 0);
18565  #endif
18566         }
18567 -       
18568 +
18569         free(p);
18570 -       
18571 +
18572         return HANDLER_GO_ON;
18573  }
18574  
18575  int mod_rrd_create_pipe(server *srv, plugin_data *p) {
18576         pid_t pid;
18577 -       
18578 +
18579         int to_rrdtool_fds[2];
18580         int from_rrdtool_fds[2];
18581 -#ifdef HAVE_FORK       
18582 +#ifdef HAVE_FORK
18583         if (pipe(to_rrdtool_fds)) {
18584 -               log_error_write(srv, __FILE__, __LINE__, "ss", 
18585 +               log_error_write(srv, __FILE__, __LINE__, "ss",
18586                                 "pipe failed: ", strerror(errno));
18587                 return -1;
18588         }
18589 -       
18590 +
18591         if (pipe(from_rrdtool_fds)) {
18592 -               log_error_write(srv, __FILE__, __LINE__, "ss", 
18593 +               log_error_write(srv, __FILE__, __LINE__, "ss",
18594                                 "pipe failed: ", strerror(errno));
18595                 return -1;
18596         }
18597 -       
18598 +
18599         /* fork, execve */
18600         switch (pid = fork()) {
18601         case 0: {
18602 @@ -117,33 +120,33 @@
18603                 int argc;
18604                 int i = 0;
18605                 char *dash = "-";
18606 -               
18607 +
18608                 /* move stdout to from_rrdtool_fd[1] */
18609                 close(STDOUT_FILENO);
18610                 dup2(from_rrdtool_fds[1], STDOUT_FILENO);
18611                 close(from_rrdtool_fds[1]);
18612                 /* not needed */
18613                 close(from_rrdtool_fds[0]);
18614 -               
18615 +
18616                 /* move the stdin to to_rrdtool_fd[0] */
18617                 close(STDIN_FILENO);
18618                 dup2(to_rrdtool_fds[0], STDIN_FILENO);
18619                 close(to_rrdtool_fds[0]);
18620                 /* not needed */
18621                 close(to_rrdtool_fds[1]);
18622 -               
18623 +
18624                 close(STDERR_FILENO);
18625 -               
18626 +
18627                 if (srv->errorlog_mode == ERRORLOG_FILE) {
18628                         dup2(srv->errorlog_fd, STDERR_FILENO);
18629                         close(srv->errorlog_fd);
18630                 }
18631 -               
18632 +
18633                 /* set up args */
18634                 argc = 3;
18635                 args = malloc(sizeof(*args) * argc);
18636                 i = 0;
18637 -               
18638 +
18639                 args[i++] = p->conf.path_rrdtool_bin->ptr;
18640                 args[i++] = dash;
18641                 args[i++] = NULL;
18642 @@ -152,12 +155,12 @@
18643                 for (i = 3; i < 256; i++) {
18644                         close(i);
18645                 }
18646 -               
18647 +
18648                 /* exec the cgi */
18649                 execv(args[0], args);
18650 -               
18651 +
18652                 log_error_write(srv, __FILE__, __LINE__, "sss", "spawing rrdtool failed: ", strerror(errno), args[0]);
18653 -               
18654 +
18655                 /* */
18656                 SEGFAULT();
18657                 break;
18658 @@ -168,19 +171,19 @@
18659                 break;
18660         default: {
18661                 /* father */
18662 -               
18663 +
18664                 close(from_rrdtool_fds[1]);
18665                 close(to_rrdtool_fds[0]);
18666 -               
18667 +
18668                 /* register PID and wait for them asyncronously */
18669                 p->write_fd = to_rrdtool_fds[1];
18670                 p->read_fd = from_rrdtool_fds[0];
18671                 p->rrdtool_pid = pid;
18672 -               
18673 +
18674                 break;
18675         }
18676         }
18677 -       
18678 +
18679         return 0;
18680  #else
18681         return -1;
18682 @@ -189,19 +192,19 @@
18683  
18684  static int mod_rrdtool_create_rrd(server *srv, plugin_data *p, plugin_config *s) {
18685         struct stat st;
18686 -       
18687 +
18688         /* check if DB already exists */
18689         if (0 == stat(s->path_rrd->ptr, &st)) {
18690                 /* check if it is plain file */
18691                 if (!S_ISREG(st.st_mode)) {
18692 -                       log_error_write(srv, __FILE__, __LINE__, "sb", 
18693 +                       log_error_write(srv, __FILE__, __LINE__, "sb",
18694                                         "not a regular file:", s->path_rrd);
18695                         return HANDLER_ERROR;
18696                 }
18697         } else {
18698                 int r ;
18699                 /* create a new one */
18700 -               
18701 +
18702                 BUFFER_COPY_STRING_CONST(p->cmd, "create ");
18703                 buffer_append_string_buffer(p->cmd, s->path_rrd);
18704                 buffer_append_string(p->cmd, " --step 60 ");
18705 @@ -220,158 +223,155 @@
18706                 buffer_append_string(p->cmd, "RRA:MIN:0.5:6:700 ");
18707                 buffer_append_string(p->cmd, "RRA:MIN:0.5:24:775 ");
18708                 buffer_append_string(p->cmd, "RRA:MIN:0.5:288:797\n");
18709 -               
18710 +
18711                 if (-1 == (r = write(p->write_fd, p->cmd->ptr, p->cmd->used - 1))) {
18712 -                       log_error_write(srv, __FILE__, __LINE__, "ss", 
18713 +                       log_error_write(srv, __FILE__, __LINE__, "ss",
18714                                 "rrdtool-write: failed", strerror(errno));
18715 -                       
18716 +
18717                         return HANDLER_ERROR;
18718                 }
18719 -               
18720 +
18721                 buffer_prepare_copy(p->resp, 4096);
18722                 if (-1 == (r = read(p->read_fd, p->resp->ptr, p->resp->size))) {
18723 -                       log_error_write(srv, __FILE__, __LINE__, "ss", 
18724 +                       log_error_write(srv, __FILE__, __LINE__, "ss",
18725                                 "rrdtool-read: failed", strerror(errno));
18726 -                       
18727 +
18728                         return HANDLER_ERROR;
18729                 }
18730 -               
18731 +
18732                 p->resp->used = r;
18733 -               
18734 +
18735                 if (p->resp->ptr[0] != 'O' ||
18736                     p->resp->ptr[1] != 'K') {
18737 -                       log_error_write(srv, __FILE__, __LINE__, "sbb", 
18738 +                       log_error_write(srv, __FILE__, __LINE__, "sbb",
18739                                 "rrdtool-response:", p->cmd, p->resp);
18740 -                       
18741 +
18742                         return HANDLER_ERROR;
18743                 }
18744         }
18745 -       
18746 +
18747         return HANDLER_GO_ON;
18748  }
18749  
18750 -#define PATCH(x) \
18751 -       p->conf.x = s->x;
18752  static int mod_rrd_patch_connection(server *srv, connection *con, plugin_data *p) {
18753         size_t i, j;
18754         plugin_config *s = p->config_storage[0];
18755 -       
18756 -       PATCH(path_rrdtool_bin);
18757 -       PATCH(path_rrd);
18758 -       
18759 +
18760 +       PATCH_OPTION(path_rrdtool_bin);
18761 +       PATCH_OPTION(path_rrd);
18762 +
18763         p->conf.bytes_written_ptr = &(s->bytes_written);
18764         p->conf.bytes_read_ptr = &(s->bytes_read);
18765         p->conf.requests_ptr = &(s->requests);
18766 -       
18767 +
18768         /* skip the first, the global context */
18769         for (i = 1; i < srv->config_context->used; i++) {
18770                 data_config *dc = (data_config *)srv->config_context->data[i];
18771                 s = p->config_storage[i];
18772 -               
18773 +
18774                 /* condition didn't match */
18775                 if (!config_check_cond(srv, con, dc)) continue;
18776 -               
18777 +
18778                 /* merge config */
18779                 for (j = 0; j < dc->value->used; j++) {
18780                         data_unset *du = dc->value->data[j];
18781 -                       
18782 +
18783                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("rrdtool.db-name"))) {
18784 -                               PATCH(path_rrd);
18785 +                               PATCH_OPTION(path_rrd);
18786                                 /* get pointers to double values */
18787 -                               
18788 +
18789                                 p->conf.bytes_written_ptr = &(s->bytes_written);
18790                                 p->conf.bytes_read_ptr = &(s->bytes_read);
18791                                 p->conf.requests_ptr = &(s->requests);
18792                         }
18793                 }
18794         }
18795 -       
18796 +
18797         return 0;
18798  }
18799 -#undef PATCH
18800  
18801  SETDEFAULTS_FUNC(mod_rrd_set_defaults) {
18802         plugin_data *p = p_d;
18803         size_t i;
18804 -       
18805 -       config_values_t cv[] = { 
18806 +
18807 +       config_values_t cv[] = {
18808                 { "rrdtool.binary",              NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },
18809                 { "rrdtool.db-name",             NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
18810                 { NULL,                          NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
18811         };
18812 -       
18813 +
18814         if (!p) return HANDLER_ERROR;
18815 -       
18816 +
18817         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
18818 -       
18819 +
18820         for (i = 0; i < srv->config_context->used; i++) {
18821                 plugin_config *s;
18822 -               
18823 +
18824                 s = calloc(1, sizeof(plugin_config));
18825                 s->path_rrdtool_bin = buffer_init();
18826                 s->path_rrd = buffer_init();
18827                 s->requests = 0;
18828                 s->bytes_written = 0;
18829                 s->bytes_read = 0;
18830 -               
18831 +
18832                 cv[0].destination = s->path_rrdtool_bin;
18833                 cv[1].destination = s->path_rrd;
18834 -               
18835 +
18836                 p->config_storage[i] = s;
18837 -       
18838 +
18839                 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
18840                         return HANDLER_ERROR;
18841                 }
18842 -               
18843 +
18844                 if (i > 0 && !buffer_is_empty(s->path_rrdtool_bin)) {
18845                         /* path_rrdtool_bin is a global option */
18846 -                       
18847 -                       log_error_write(srv, __FILE__, __LINE__, "s", 
18848 +
18849 +                       log_error_write(srv, __FILE__, __LINE__, "s",
18850                                         "rrdtool.binary can only be set as a global option.");
18851 -                       
18852 +
18853                         return HANDLER_ERROR;
18854                 }
18855 -               
18856 +
18857         }
18858 -       
18859 +
18860         p->conf.path_rrdtool_bin = p->config_storage[0]->path_rrdtool_bin;
18861         p->rrdtool_running = 0;
18862 -       
18863 +
18864         /* check for dir */
18865 -       
18866 +
18867         if (buffer_is_empty(p->conf.path_rrdtool_bin)) {
18868 -               log_error_write(srv, __FILE__, __LINE__, "s", 
18869 +               log_error_write(srv, __FILE__, __LINE__, "s",
18870                                 "rrdtool.binary has to be set");
18871                 return HANDLER_ERROR;
18872         }
18873 -       
18874 +
18875         /* open the pipe to rrdtool */
18876         if (mod_rrd_create_pipe(srv, p)) {
18877                 return HANDLER_ERROR;
18878         }
18879 -       
18880 +
18881         p->rrdtool_running = 1;
18882 -               
18883 +
18884         return HANDLER_GO_ON;
18885  }
18886  
18887  TRIGGER_FUNC(mod_rrd_trigger) {
18888         plugin_data *p = p_d;
18889         size_t i;
18890 -       
18891 +
18892         if (!p->rrdtool_running) return HANDLER_GO_ON;
18893         if ((srv->cur_ts % 60) != 0) return HANDLER_GO_ON;
18894 -       
18895 +
18896         for (i = 0; i < srv->config_context->used; i++) {
18897                 plugin_config *s = p->config_storage[i];
18898                 int r;
18899 -               
18900 +
18901                 if (buffer_is_empty(s->path_rrd)) continue;
18902 -       
18903 +
18904                 /* write the data down every minute */
18905 -               
18906 +
18907                 if (HANDLER_GO_ON != mod_rrdtool_create_rrd(srv, p, s)) return HANDLER_ERROR;
18908 -               
18909 +
18910                 BUFFER_COPY_STRING_CONST(p->cmd, "update ");
18911                 buffer_append_string_buffer(p->cmd, s->path_rrd);
18912                 BUFFER_APPEND_STRING_CONST(p->cmd, " N:");
18913 @@ -381,69 +381,69 @@
18914                 BUFFER_APPEND_STRING_CONST(p->cmd, ":");
18915                 buffer_append_long(p->cmd, s->requests);
18916                 BUFFER_APPEND_STRING_CONST(p->cmd, "\n");
18917 -               
18918 +
18919                 if (-1 == (r = write(p->write_fd, p->cmd->ptr, p->cmd->used - 1))) {
18920                         p->rrdtool_running = 0;
18921 -                       
18922 -                       log_error_write(srv, __FILE__, __LINE__, "ss", 
18923 +
18924 +                       log_error_write(srv, __FILE__, __LINE__, "ss",
18925                                         "rrdtool-write: failed", strerror(errno));
18926 -                       
18927 +
18928                         return HANDLER_ERROR;
18929                 }
18930 -               
18931 +
18932                 buffer_prepare_copy(p->resp, 4096);
18933                 if (-1 == (r = read(p->read_fd, p->resp->ptr, p->resp->size))) {
18934                         p->rrdtool_running = 0;
18935 -                       
18936 -                       log_error_write(srv, __FILE__, __LINE__, "ss", 
18937 +
18938 +                       log_error_write(srv, __FILE__, __LINE__, "ss",
18939                                         "rrdtool-read: failed", strerror(errno));
18940 -                       
18941 +
18942                         return HANDLER_ERROR;
18943                 }
18944 -               
18945 +
18946                 p->resp->used = r;
18947 -               
18948 +
18949                 if (p->resp->ptr[0] != 'O' ||
18950                     p->resp->ptr[1] != 'K') {
18951                         p->rrdtool_running = 0;
18952 -                       
18953 -                       log_error_write(srv, __FILE__, __LINE__, "sbb", 
18954 +
18955 +                       log_error_write(srv, __FILE__, __LINE__, "sbb",
18956                                         "rrdtool-response:", p->cmd, p->resp);
18957 -                       
18958 +
18959                         return HANDLER_ERROR;
18960                 }
18961                 s->requests = 0;
18962                 s->bytes_written = 0;
18963                 s->bytes_read = 0;
18964         }
18965 -       
18966 +
18967         return HANDLER_GO_ON;
18968  }
18969  
18970  REQUESTDONE_FUNC(mod_rrd_account) {
18971         plugin_data *p = p_d;
18972 -       
18973 +
18974         mod_rrd_patch_connection(srv, con, p);
18975 -       
18976 +
18977         *(p->conf.requests_ptr)      += 1;
18978         *(p->conf.bytes_written_ptr) += con->bytes_written;
18979         *(p->conf.bytes_read_ptr)    += con->bytes_read;
18980 -       
18981 +
18982         return HANDLER_GO_ON;
18983  }
18984  
18985  int mod_rrdtool_plugin_init(plugin *p) {
18986         p->version     = LIGHTTPD_VERSION_ID;
18987         p->name        = buffer_init_string("rrd");
18988 -       
18989 +
18990         p->init        = mod_rrd_init;
18991         p->cleanup     = mod_rrd_free;
18992         p->set_defaults= mod_rrd_set_defaults;
18993 -       
18994 +
18995         p->handle_trigger      = mod_rrd_trigger;
18996         p->handle_request_done = mod_rrd_account;
18997 -       
18998 +
18999         p->data        = NULL;
19000 -       
19001 +
19002         return 0;
19003  }
19004
19005 Property changes on: src/mod_rrdtool.c
19006 ___________________________________________________________________
19007 Name: svn:eol-style
19008    + native
19009
19010
19011 Property changes on: src/inet_ntop_cache.h
19012 ___________________________________________________________________
19013 Name: svn:eol-style
19014    + native
19015
19016 Index: src/mod_ssi_expr.c
19017 ===================================================================
19018 --- src/mod_ssi_expr.c  (.../tags/lighttpd-1.4.11)      (revision 1159)
19019 +++ src/mod_ssi_expr.c  (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
19020 @@ -11,9 +11,9 @@
19021         const char *input;
19022         size_t offset;
19023         size_t size;
19024 -       
19025 +
19026         int line_pos;
19027 -       
19028 +
19029         int in_key;
19030         int in_brace;
19031         int in_cond;
19032 @@ -21,15 +21,15 @@
19033  
19034  ssi_val_t *ssi_val_init() {
19035         ssi_val_t *s;
19036 -       
19037 +
19038         s = calloc(1, sizeof(*s));
19039 -       
19040 +
19041         return s;
19042  }
19043  
19044  void ssi_val_free(ssi_val_t *s) {
19045         if (s->str) buffer_free(s->str);
19046 -       
19047 +
19048         free(s);
19049  }
19050  
19051 @@ -45,175 +45,175 @@
19052                               ssi_tokenizer_t *t, int *token_id, buffer *token) {
19053         int tid = 0;
19054         size_t i;
19055 -       
19056 +
19057         UNUSED(con);
19058  
19059         for (tid = 0; tid == 0 && t->offset < t->size && t->input[t->offset] ; ) {
19060                 char c = t->input[t->offset];
19061                 data_string *ds;
19062 -               
19063 +
19064                 switch (c) {
19065 -               case '=': 
19066 +               case '=':
19067                         tid = TK_EQ;
19068 -                       
19069 +
19070                         t->offset++;
19071                         t->line_pos++;
19072 -                       
19073 +
19074                         buffer_copy_string(token, "(=)");
19075 -                       
19076 +
19077                         break;
19078                 case '>':
19079                         if (t->input[t->offset + 1] == '=') {
19080                                 t->offset += 2;
19081                                 t->line_pos += 2;
19082 -                               
19083 +
19084                                 tid = TK_GE;
19085 -                               
19086 +
19087                                 buffer_copy_string(token, "(>=)");
19088                         } else {
19089                                 t->offset += 1;
19090                                 t->line_pos += 1;
19091 -                               
19092 +
19093                                 tid = TK_GT;
19094 -                               
19095 +
19096                                 buffer_copy_string(token, "(>)");
19097                         }
19098 -                       
19099 +
19100                         break;
19101                 case '<':
19102                         if (t->input[t->offset + 1] == '=') {
19103                                 t->offset += 2;
19104                                 t->line_pos += 2;
19105 -                               
19106 +
19107                                 tid = TK_LE;
19108 -                               
19109 +
19110                                 buffer_copy_string(token, "(<=)");
19111                         } else {
19112                                 t->offset += 1;
19113                                 t->line_pos += 1;
19114 -                               
19115 +
19116                                 tid = TK_LT;
19117 -                               
19118 +
19119                                 buffer_copy_string(token, "(<)");
19120                         }
19121 -                       
19122 +
19123                         break;
19124 -                       
19125 +
19126                 case '!':
19127                         if (t->input[t->offset + 1] == '=') {
19128                                 t->offset += 2;
19129                                 t->line_pos += 2;
19130 -                               
19131 +
19132                                 tid = TK_NE;
19133 -                               
19134 +
19135                                 buffer_copy_string(token, "(!=)");
19136                         } else {
19137                                 t->offset += 1;
19138                                 t->line_pos += 1;
19139 -                               
19140 +
19141                                 tid = TK_NOT;
19142 -                               
19143 +
19144                                 buffer_copy_string(token, "(!)");
19145                         }
19146 -                       
19147 +
19148                         break;
19149                 case '&':
19150                         if (t->input[t->offset + 1] == '&') {
19151                                 t->offset += 2;
19152                                 t->line_pos += 2;
19153 -                               
19154 +
19155                                 tid = TK_AND;
19156 -                               
19157 +
19158                                 buffer_copy_string(token, "(&&)");
19159                         } else {
19160 -                               log_error_write(srv, __FILE__, __LINE__, "sds", 
19161 -                                               "pos:", t->line_pos, 
19162 +                               log_error_write(srv, __FILE__, __LINE__, "sds",
19163 +                                               "pos:", t->line_pos,
19164                                                 "missing second &");
19165                                 return -1;
19166                         }
19167 -                       
19168 +
19169                         break;
19170                 case '|':
19171                         if (t->input[t->offset + 1] == '|') {
19172                                 t->offset += 2;
19173                                 t->line_pos += 2;
19174 -                               
19175 +
19176                                 tid = TK_OR;
19177 -                               
19178 +
19179                                 buffer_copy_string(token, "(||)");
19180                         } else {
19181 -                               log_error_write(srv, __FILE__, __LINE__, "sds", 
19182 -                                               "pos:", t->line_pos, 
19183 +                               log_error_write(srv, __FILE__, __LINE__, "sds",
19184 +                                               "pos:", t->line_pos,
19185                                                 "missing second |");
19186                                 return -1;
19187                         }
19188 -                       
19189 +
19190                         break;
19191                 case '\t':
19192                 case ' ':
19193                         t->offset++;
19194                         t->line_pos++;
19195                         break;
19196 -                       
19197 +
19198                 case '\'':
19199                         /* search for the terminating " */
19200                         for (i = 1; t->input[t->offset + i] && t->input[t->offset + i] != '\'';  i++);
19201 -                       
19202 +
19203                         if (t->input[t->offset + i]) {
19204                                 tid = TK_VALUE;
19205 -                               
19206 +
19207                                 buffer_copy_string_len(token, t->input + t->offset + 1, i-1);
19208 -                               
19209 +
19210                                 t->offset += i + 1;
19211                                 t->line_pos += i + 1;
19212                         } else {
19213                                 /* ERROR */
19214 -                               
19215 -                               log_error_write(srv, __FILE__, __LINE__, "sds", 
19216 -                                               "pos:", t->line_pos, 
19217 +
19218 +                               log_error_write(srv, __FILE__, __LINE__, "sds",
19219 +                                               "pos:", t->line_pos,
19220                                                 "missing closing quote");
19221 -                               
19222 +
19223                                 return -1;
19224                         }
19225 -                       
19226 +
19227                         break;
19228                 case '(':
19229                         t->offset++;
19230                         t->in_brace++;
19231 -                               
19232 +
19233                         tid = TK_LPARAN;
19234 -                               
19235 +
19236                         buffer_copy_string(token, "(");
19237                         break;
19238                 case ')':
19239                         t->offset++;
19240                         t->in_brace--;
19241 -                               
19242 +
19243                         tid = TK_RPARAN;
19244 -                               
19245 +
19246                         buffer_copy_string(token, ")");
19247                         break;
19248                 case '$':
19249                         if (t->input[t->offset + 1] == '{') {
19250                                 for (i = 2; t->input[t->offset + i] && t->input[t->offset + i] != '}';  i++);
19251 -                               
19252 +
19253                                 if (t->input[t->offset + i] != '}') {
19254 -                                       log_error_write(srv, __FILE__, __LINE__, "sds", 
19255 -                                                       "pos:", t->line_pos, 
19256 +                                       log_error_write(srv, __FILE__, __LINE__, "sds",
19257 +                                                       "pos:", t->line_pos,
19258                                                         "missing closing quote");
19259 -                                       
19260 +
19261                                         return -1;
19262                                 }
19263 -                               
19264 +
19265                                 buffer_copy_string_len(token, t->input + t->offset + 2, i-3);
19266                         } else {
19267                                 for (i = 1; isalpha(t->input[t->offset + i]) || t->input[t->offset + i] == '_';  i++);
19268 -                               
19269 +
19270                                 buffer_copy_string_len(token, t->input + t->offset + 1, i-1);
19271                         }
19272 -                       
19273 +
19274                         tid = TK_VALUE;
19275 -                       
19276 +
19277                         if (NULL != (ds = (data_string *)array_get_element(p->ssi_cgi_env, token->ptr))) {
19278                                 buffer_copy_string_buffer(token, ds->value);
19279                         } else if (NULL != (ds = (data_string *)array_get_element(p->ssi_vars, token->ptr))) {
19280 @@ -221,16 +221,16 @@
19281                         } else {
19282                                 buffer_copy_string(token, "");
19283                         }
19284 -                               
19285 +
19286                         t->offset += i;
19287                         t->line_pos += i;
19288 -                       
19289 +
19290                         break;
19291                 default:
19292                         for (i = 0; isgraph(t->input[t->offset + i]);  i++) {
19293                                 char d = t->input[t->offset + i];
19294                                 switch(d) {
19295 -                               case ' ': 
19296 +                               case ' ':
19297                                 case '\t':
19298                                 case ')':
19299                                 case '(':
19300 @@ -244,25 +244,25 @@
19301                                         break;
19302                                 }
19303                         }
19304 -                       
19305 +
19306                         tid = TK_VALUE;
19307 -                               
19308 +
19309                         buffer_copy_string_len(token, t->input + t->offset, i);
19310 -                               
19311 +
19312                         t->offset += i;
19313                         t->line_pos += i;
19314 -                       
19315 +
19316                         break;
19317                 }
19318         }
19319 -                       
19320 +
19321         if (tid) {
19322                 *token_id = tid;
19323 -               
19324 +
19325                 return 1;
19326         } else if (t->offset < t->size) {
19327 -               log_error_write(srv, __FILE__, __LINE__, "sds", 
19328 -                               "pos:", t->line_pos, 
19329 +               log_error_write(srv, __FILE__, __LINE__, "sds",
19330 +                               "pos:", t->line_pos,
19331                                 "foobar");
19332         }
19333         return 0;
19334 @@ -275,50 +275,50 @@
19335         buffer *token;
19336         ssi_ctx_t context;
19337         int ret;
19338 -       
19339 +
19340         t.input = expr;
19341         t.offset = 0;
19342         t.size = strlen(expr);
19343         t.line_pos = 1;
19344 -       
19345 +
19346         t.in_key = 1;
19347         t.in_brace = 0;
19348         t.in_cond = 0;
19349 -       
19350 +
19351         context.ok = 1;
19352         context.srv = srv;
19353 -       
19354 +
19355         /* default context */
19356 -       
19357 +
19358         pParser = ssiexprparserAlloc( malloc );
19359         token = buffer_init();
19360         while((1 == (ret = ssi_expr_tokenizer(srv, con, p, &t, &token_id, token))) && context.ok) {
19361                 ssiexprparser(pParser, token_id, token, &context);
19362 -               
19363 +
19364                 token = buffer_init();
19365         }
19366         ssiexprparser(pParser, 0, token, &context);
19367         ssiexprparserFree(pParser, free );
19368 -       
19369 +
19370         buffer_free(token);
19371 -       
19372 +
19373         if (ret == -1) {
19374 -               log_error_write(srv, __FILE__, __LINE__, "s", 
19375 +               log_error_write(srv, __FILE__, __LINE__, "s",
19376                                 "expr parser failed");
19377                 return -1;
19378         }
19379 -       
19380 +
19381         if (context.ok == 0) {
19382 -               log_error_write(srv, __FILE__, __LINE__, "sds", 
19383 -                               "pos:", t.line_pos, 
19384 +               log_error_write(srv, __FILE__, __LINE__, "sds",
19385 +                               "pos:", t.line_pos,
19386                                 "parser failed somehow near here");
19387                 return -1;
19388         }
19389  #if 0
19390 -       log_error_write(srv, __FILE__, __LINE__, "ssd", 
19391 +       log_error_write(srv, __FILE__, __LINE__, "ssd",
19392                         "expr: ",
19393                         expr,
19394                         context.val.bo);
19395 -#endif 
19396 +#endif
19397         return context.val.bo;
19398  }
19399
19400 Property changes on: src/mod_ssi_expr.c
19401 ___________________________________________________________________
19402 Name: svn:eol-style
19403    + native
19404
19405 Index: src/response.c
19406 ===================================================================
19407 --- src/response.c      (.../tags/lighttpd-1.4.11)      (revision 1159)
19408 +++ src/response.c      (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
19409 @@ -7,7 +7,6 @@
19410  #include <stdlib.h>
19411  #include <string.h>
19412  #include <time.h>
19413 -#include <unistd.h>
19414  #include <ctype.h>
19415  #include <assert.h>
19416  
19417 @@ -24,15 +23,17 @@
19418  #include "plugin.h"
19419  
19420  #include "sys-socket.h"
19421 +#include "sys-files.h"
19422 +#include "sys-strings.h"
19423  
19424  int http_response_write_header(server *srv, connection *con) {
19425         buffer *b;
19426         size_t i;
19427         int have_date = 0;
19428         int have_server = 0;
19429 -       
19430 +
19431         b = chunkqueue_get_prepend_buffer(con->write_queue);
19432 -       
19433 +
19434         if (con->request.http_version == HTTP_VERSION_1_1) {
19435                 BUFFER_COPY_STRING_CONST(b, "HTTP/1.1 ");
19436         } else {
19437 @@ -41,25 +42,26 @@
19438         buffer_append_long(b, con->http_status);
19439         BUFFER_APPEND_STRING_CONST(b, " ");
19440         buffer_append_string(b, get_http_status_name(con->http_status));
19441 -       
19442 +
19443         if (con->request.http_version != HTTP_VERSION_1_1 || con->keep_alive == 0) {
19444                 BUFFER_APPEND_STRING_CONST(b, "\r\nConnection: ");
19445                 buffer_append_string(b, con->keep_alive ? "keep-alive" : "close");
19446         }
19447 -       
19448 +
19449         if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
19450                 BUFFER_APPEND_STRING_CONST(b, "\r\nTransfer-Encoding: chunked");
19451         }
19452 -       
19453 -       
19454 +
19455 +
19456         /* add all headers */
19457         for (i = 0; i < con->response.headers->used; i++) {
19458                 data_string *ds;
19459 -               
19460 +
19461                 ds = (data_string *)con->response.headers->data[i];
19462 -               
19463 +
19464                 if (ds->value->used && ds->key->used &&
19465 -                   0 != strncmp(ds->key->ptr, "X-LIGHTTPD-", sizeof("X-LIGHTTPD-") - 1)) {
19466 +                   0 != strncmp(ds->key->ptr, "X-LIGHTTPD-", sizeof("X-LIGHTTPD-") - 1) &&
19467 +                   0 != strcasecmp(ds->key->ptr, "X-Sendfile")) {
19468                         if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Date"))) have_date = 1;
19469                         if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Server"))) have_server = 1;
19470  
19471 @@ -68,28 +70,28 @@
19472                         BUFFER_APPEND_STRING_CONST(b, ": ");
19473                         buffer_append_string_buffer(b, ds->value);
19474  #if 0
19475 -                       log_error_write(srv, __FILE__, __LINE__, "bb", 
19476 +                       log_error_write(srv, __FILE__, __LINE__, "bb",
19477                                         ds->key, ds->value);
19478  #endif
19479                 }
19480         }
19481 -       
19482 +
19483         if (!have_date) {
19484                 /* HTTP/1.1 requires a Date: header */
19485                 BUFFER_APPEND_STRING_CONST(b, "\r\nDate: ");
19486 -       
19487 +
19488                 /* cache the generated timestamp */
19489                 if (srv->cur_ts != srv->last_generated_date_ts) {
19490                         buffer_prepare_copy(srv->ts_date_str, 255);
19491 -               
19492 -                       strftime(srv->ts_date_str->ptr, srv->ts_date_str->size - 1, 
19493 +
19494 +                       strftime(srv->ts_date_str->ptr, srv->ts_date_str->size - 1,
19495                                  "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(srv->cur_ts)));
19496 -                        
19497 +
19498                         srv->ts_date_str->used = strlen(srv->ts_date_str->ptr) + 1;
19499 -               
19500 +
19501                         srv->last_generated_date_ts = srv->cur_ts;
19502                 }
19503 -       
19504 +
19505                 buffer_append_string_buffer(b, srv->ts_date_str);
19506         }
19507  
19508 @@ -101,16 +103,16 @@
19509                         buffer_append_string_buffer(b, con->conf.server_tag);
19510                 }
19511         }
19512 -       
19513 +
19514         BUFFER_APPEND_STRING_CONST(b, "\r\n\r\n");
19515 -       
19516 -       
19517 +
19518 +
19519         con->bytes_header = b->used - 1;
19520 -       
19521 +
19522         if (con->conf.log_response_header) {
19523                 log_error_write(srv, __FILE__, __LINE__, "sSb", "Response-Header:", "\n", b);
19524         }
19525 -       
19526 +
19527         return 0;
19528  }
19529  
19530 @@ -118,71 +120,71 @@
19531  
19532  handler_t http_response_prepare(server *srv, connection *con) {
19533         handler_t r;
19534 -       
19535 -       /* looks like someone has already done a decision */
19536 -       if (con->mode == DIRECT && 
19537 +
19538 +       /* looks like someone has already made a decision */
19539 +       if (con->mode == DIRECT &&
19540             (con->http_status != 0 && con->http_status != 200)) {
19541                 /* remove a packets in the queue */
19542                 if (con->file_finished == 0) {
19543                         chunkqueue_reset(con->write_queue);
19544                 }
19545 -               
19546 +
19547                 return HANDLER_FINISHED;
19548         }
19549 -       
19550 +
19551         /* no decision yet, build conf->filename */
19552         if (con->mode == DIRECT && con->physical.path->used == 0) {
19553                 char *qstr;
19554  
19555 -               /* we only come here when we have the parse the full request again
19556 -                * 
19557 -                * a HANDLER_COMEBACK from mod_rewrite and mod_fastcgi might be a 
19558 +               /* we only come here when we have to parse the full request again
19559 +                *
19560 +                * a HANDLER_COMEBACK from mod_rewrite and mod_fastcgi might be a
19561                  * problem here as mod_setenv might get called multiple times
19562                  *
19563                  * fastcgi-auth might lead to a COMEBACK too
19564                  * fastcgi again dead server too
19565                  *
19566                  * mod_compress might add headers twice too
19567 -                * 
19568 +                *
19569                  *  */
19570 -               
19571 +
19572                 if (con->conf.log_condition_handling) {
19573                         log_error_write(srv, __FILE__, __LINE__,  "s",  "run condition");
19574                 }
19575                 config_patch_connection(srv, con, COMP_SERVER_SOCKET); /* SERVERsocket */
19576 -               
19577 +
19578                 /**
19579                  * prepare strings
19580 -                * 
19581 -                * - uri.path_raw 
19582 +                *
19583 +                * - uri.path_raw
19584                  * - uri.path (secure)
19585                  * - uri.query
19586 -                * 
19587 +                *
19588                  */
19589 -               
19590 -               /** 
19591 +
19592 +               /**
19593                  * Name according to RFC 2396
19594 -                * 
19595 +                *
19596                  * - scheme
19597                  * - authority
19598                  * - path
19599                  * - query
19600 -                * 
19601 +                *
19602                  * (scheme)://(authority)(path)?(query)
19603 -                * 
19604 -                * 
19605 +                *
19606 +                *
19607                  */
19608 -       
19609 +
19610                 buffer_copy_string(con->uri.scheme, con->conf.is_ssl ? "https" : "http");
19611                 buffer_copy_string_buffer(con->uri.authority, con->request.http_host);
19612                 buffer_to_lower(con->uri.authority);
19613 -               
19614 +
19615                 config_patch_connection(srv, con, COMP_HTTP_HOST);      /* Host:        */
19616                 config_patch_connection(srv, con, COMP_HTTP_REMOTEIP);  /* Client-IP */
19617                 config_patch_connection(srv, con, COMP_HTTP_REFERER);   /* Referer:     */
19618                 config_patch_connection(srv, con, COMP_HTTP_USERAGENT); /* User-Agent:  */
19619                 config_patch_connection(srv, con, COMP_HTTP_COOKIE);    /* Cookie:  */
19620 -               
19621 +
19622                 /** extract query string from request.uri */
19623                 if (NULL != (qstr = strchr(con->request.uri->ptr, '?'))) {
19624                         buffer_copy_string    (con->uri.query, qstr + 1);
19625 @@ -200,22 +202,22 @@
19626                         log_error_write(srv, __FILE__, __LINE__,  "sb", "URI-path     : ", con->uri.path_raw);
19627                         log_error_write(srv, __FILE__, __LINE__,  "sb", "URI-query    : ", con->uri.query);
19628                 }
19629 -               
19630 +
19631                 /* disable keep-alive if requested */
19632 -               
19633 +
19634                 if (con->request_count > con->conf.max_keep_alive_requests) {
19635                         con->keep_alive = 0;
19636                 }
19637 -               
19638 -               
19639 +
19640 +
19641                 /**
19642 -                *  
19643 -                * call plugins 
19644 -                * 
19645 +                *
19646 +                * call plugins
19647 +                *
19648                  * - based on the raw URL
19649 -                * 
19650 +                *
19651                  */
19652 -               
19653 +
19654                 switch(r = plugins_call_handle_uri_raw(srv, con)) {
19655                 case HANDLER_GO_ON:
19656                         break;
19657 @@ -229,14 +231,14 @@
19658                         break;
19659                 }
19660  
19661 -               /* build filename 
19662 +               /* build filename
19663                  *
19664                  * - decode url-encodings  (e.g. %20 -> ' ')
19665                  * - remove path-modifiers (e.g. /../)
19666                  */
19667 -               
19668 -               
19669 -               
19670 +
19671 +
19672 +
19673                 if (con->request.http_method == HTTP_METHOD_OPTIONS &&
19674                     con->uri.path_raw->ptr[0] == '*' && con->uri.path_raw->ptr[1] == '\0') {
19675                         /* OPTIONS * ... */
19676 @@ -253,15 +255,20 @@
19677                 }
19678  
19679                 /**
19680 -                *  
19681 -                * call plugins 
19682 -                * 
19683 +                *
19684 +                * call plugins
19685 +                *
19686                  * - based on the clean URL
19687 -                * 
19688 +                *
19689                  */
19690 -               
19691 +
19692                 config_patch_connection(srv, con, COMP_HTTP_URL); /* HTTPurl */
19693 -               
19694 +
19695 +               /* do we have to downgrade to 1.0 ? */
19696 +               if (!con->conf.allow_http11) {
19697 +                       con->request.http_version = HTTP_VERSION_1_0;
19698 +               }
19699 +
19700                 switch(r = plugins_call_handle_uri_clean(srv, con)) {
19701                 case HANDLER_GO_ON:
19702                         break;
19703 @@ -274,11 +281,11 @@
19704                         log_error_write(srv, __FILE__, __LINE__, "");
19705                         break;
19706                 }
19707 -               
19708 +
19709                 if (con->request.http_method == HTTP_METHOD_OPTIONS &&
19710                     con->uri.path->ptr[0] == '*' && con->uri.path_raw->ptr[1] == '\0') {
19711 -                       /* option requests are handled directly without checking of the path */
19712 -               
19713 +                       /* option requests are handled directly without checking the path */
19714 +
19715                         response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("OPTIONS, GET, HEAD, POST"));
19716  
19717                         con->http_status = 200;
19718 @@ -288,46 +295,47 @@
19719                 }
19720  
19721                 /***
19722 -                * 
19723 -                * border 
19724 -                * 
19725 +                *
19726 +                * border
19727 +                *
19728                  * logical filename (URI) becomes a physical filename here
19729 -                * 
19730 -                * 
19731 -                * 
19732 +                *
19733 +                *
19734 +                *
19735                  */
19736 -               
19737 -               
19738 -               
19739 -               
19740 +
19741 +
19742 +
19743 +
19744                 /* 1. stat()
19745                  * ... ISREG() -> ok, go on
19746                  * ... ISDIR() -> index-file -> redirect
19747 -                * 
19748 -                * 2. pathinfo() 
19749 +                *
19750 +                * 2. pathinfo()
19751                  * ... ISREG()
19752 -                * 
19753 +                *
19754                  * 3. -> 404
19755 -                * 
19756 +                *
19757                  */
19758 -               
19759 +
19760                 /*
19761                  * SEARCH DOCUMENT ROOT
19762                  */
19763 -               
19764 +
19765                 /* set a default */
19766 -               
19767 +
19768                 buffer_copy_string_buffer(con->physical.doc_root, con->conf.document_root);
19769                 buffer_copy_string_buffer(con->physical.rel_path, con->uri.path);
19770 -               
19771 -#if defined(__WIN32) || defined(__CYGWIN__)
19772 -               /* strip dots from the end and spaces
19773 +
19774 +               filename_unix2local(con->physical.rel_path);
19775 +#if defined(_WIN32) || defined(__CYGWIN__)
19776 +               /* strip dots and spaces from the end
19777                  *
19778                  * windows/dos handle those filenames as the same file
19779                  *
19780                  * foo == foo. == foo..... == "foo...   " == "foo..  ./"
19781                  *
19782 -                * This will affect in some cases PATHINFO
19783 +                * This will affect PATHINFO in some cases
19784                  *
19785                  * on native windows we could prepend the filename with \\?\ to circumvent
19786                  * this behaviour. I have no idea how to push this through cygwin
19787 @@ -377,36 +385,41 @@
19788                         log_error_write(srv, __FILE__, __LINE__, "");
19789                         break;
19790                 }
19791 -               
19792 -               /* MacOS X and Windows can't distiguish between upper and lower-case 
19793 -                * 
19794 -                * convert to lower-case
19795 +
19796 +               /* The default Mac OS X and Windows filesystems can't distiguish between
19797 +                * upper- and lowercase, so convert to lowercase
19798                  */
19799                 if (con->conf.force_lowercase_filenames) {
19800                         buffer_to_lower(con->physical.rel_path);
19801                 }
19802  
19803 -               /* the docroot plugins might set the servername, if they don't we take http-host */
19804 +               /* the docroot plugins might set the servername; if they don't we take http-host */
19805                 if (buffer_is_empty(con->server_name)) {
19806                         buffer_copy_string_buffer(con->server_name, con->uri.authority);
19807                 }
19808 -               
19809 -               /** 
19810 -                * create physical filename 
19811 +
19812 +               /**
19813 +                * create physical filename
19814                  * -> physical.path = docroot + rel_path
19815 -                * 
19816 +                *
19817                  */
19818 -               
19819 +
19820                 buffer_copy_string_buffer(con->physical.path, con->physical.doc_root);
19821 -               BUFFER_APPEND_SLASH(con->physical.path);
19822 +               PATHNAME_APPEND_SLASH(con->physical.path);
19823                 buffer_copy_string_buffer(con->physical.basedir, con->physical.path);
19824                 if (con->physical.rel_path->used &&
19825 -                   con->physical.rel_path->ptr[0] == '/') {
19826 +                   con->physical.rel_path->ptr[0] == DIR_SEPERATOR) {
19827                         buffer_append_string_len(con->physical.path, con->physical.rel_path->ptr + 1, con->physical.rel_path->used - 2);
19828                 } else {
19829                         buffer_append_string_buffer(con->physical.path, con->physical.rel_path);
19830                 }
19831  
19832 +        /* win32: directories can't have a trailing slash */
19833 +        if (con->physical.path->ptr[con->physical.path->used - 2] == DIR_SEPERATOR) {
19834 +            con->physical.path->ptr[con->physical.path->used - 2] = '\0';
19835 +            con->physical.path->used--;
19836 +        }
19837 +
19838                 if (con->conf.log_request_handling) {
19839                         log_error_write(srv, __FILE__, __LINE__,  "s",  "-- after doc_root");
19840                         log_error_write(srv, __FILE__, __LINE__,  "sb", "Doc-Root     :", con->physical.doc_root);
19841 @@ -426,7 +439,7 @@
19842                         log_error_write(srv, __FILE__, __LINE__, "");
19843                         break;
19844                 }
19845 -               
19846 +
19847                 if (con->conf.log_request_handling) {
19848                         log_error_write(srv, __FILE__, __LINE__,  "s",  "-- logical -> physical");
19849                         log_error_write(srv, __FILE__, __LINE__,  "sb", "Doc-Root     :", con->physical.doc_root);
19850 @@ -434,38 +447,38 @@
19851                         log_error_write(srv, __FILE__, __LINE__,  "sb", "Path         :", con->physical.path);
19852                 }
19853         }
19854 -       
19855 -       /* 
19856 -        * Noone catched away the file from normal path of execution yet (like mod_access)
19857 -        * 
19858 +
19859 +       /*
19860 +        * No one took the file away from the normal path of execution yet (like mod_access)
19861 +        *
19862          * Go on and check of the file exists at all
19863          */
19864 -       
19865 +
19866         if (con->mode == DIRECT) {
19867                 char *slash = NULL;
19868                 char *pathinfo = NULL;
19869                 int found = 0;
19870                 stat_cache_entry *sce = NULL;
19871 -               
19872 +
19873                 if (con->conf.log_request_handling) {
19874                         log_error_write(srv, __FILE__, __LINE__,  "s",  "-- handling physical path");
19875                         log_error_write(srv, __FILE__, __LINE__,  "sb", "Path         :", con->physical.path);
19876                 }
19877 -               
19878 +
19879                 if (HANDLER_ERROR != stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
19880                         /* file exists */
19881 -                       
19882 +
19883                         if (con->conf.log_request_handling) {
19884                                 log_error_write(srv, __FILE__, __LINE__,  "s",  "-- file found");
19885                                 log_error_write(srv, __FILE__, __LINE__,  "sb", "Path         :", con->physical.path);
19886                         }
19887 -                       
19888 +
19889                         if (S_ISDIR(sce->st.st_mode)) {
19890 -                               if (con->physical.path->ptr[con->physical.path->used - 2] != '/') {
19891 +                               if (con->uri.path->ptr[con->uri.path->used - 2] != '/') {
19892                                         /* redirect to .../ */
19893 -                                       
19894 +
19895                                         http_response_redirect_to_directory(srv, con);
19896 -                                       
19897 +
19898                                         return HANDLER_FINISHED;
19899                                 }
19900                         } else if (!S_ISREG(sce->st.st_mode)) {
19901 @@ -477,12 +490,12 @@
19902                         switch (errno) {
19903                         case EACCES:
19904                                 con->http_status = 403;
19905 -       
19906 +
19907                                 if (con->conf.log_request_handling) {
19908                                         log_error_write(srv, __FILE__, __LINE__,  "s",  "-- access denied");
19909                                         log_error_write(srv, __FILE__, __LINE__,  "sb", "Path         :", con->physical.path);
19910                                 }
19911 -                       
19912 +
19913                                 buffer_reset(con->physical.path);
19914                                 return HANDLER_FINISHED;
19915                         case ENOENT:
19916 @@ -499,77 +512,77 @@
19917                                 /* PATH_INFO ! :) */
19918                                 break;
19919                         default:
19920 -                               /* we have no idea what happend. let's tell the user so. */
19921 +                               /* we have no idea what happened, so tell the user. */
19922                                 con->http_status = 500;
19923                                 buffer_reset(con->physical.path);
19924 -                               
19925 +
19926                                 log_error_write(srv, __FILE__, __LINE__, "ssbsb",
19927                                                 "file not found ... or so: ", strerror(errno),
19928                                                 con->uri.path,
19929                                                 "->", con->physical.path);
19930 -                               
19931 +
19932                                 return HANDLER_FINISHED;
19933                         }
19934 -                       
19935 +
19936                         /* not found, perhaps PATHINFO */
19937 -                       
19938 +
19939                         buffer_copy_string_buffer(srv->tmp_buf, con->physical.path);
19940 -                       
19941 +
19942                         do {
19943                                 struct stat st;
19944 -                               
19945 +
19946                                 if (slash) {
19947                                         buffer_copy_string_len(con->physical.path, srv->tmp_buf->ptr, slash - srv->tmp_buf->ptr);
19948                                 } else {
19949                                         buffer_copy_string_buffer(con->physical.path, srv->tmp_buf);
19950                                 }
19951 -                               
19952 +
19953                                 if (0 == stat(con->physical.path->ptr, &(st)) &&
19954                                     S_ISREG(st.st_mode)) {
19955                                         found = 1;
19956                                         break;
19957                                 }
19958 -                               
19959 +
19960                                 if (pathinfo != NULL) {
19961                                         *pathinfo = '\0';
19962                                 }
19963                                 slash = strrchr(srv->tmp_buf->ptr, '/');
19964 -                               
19965 +
19966                                 if (pathinfo != NULL) {
19967                                         /* restore '/' */
19968                                         *pathinfo = '/';
19969                                 }
19970 -                               
19971 +
19972                                 if (slash) pathinfo = slash;
19973                         } while ((found == 0) && (slash != NULL) && (slash - srv->tmp_buf->ptr > con->physical.basedir->used - 2));
19974 -                       
19975 +
19976                         if (found == 0) {
19977 -                               /* no it really doesn't exists */
19978 +                               /* no, it really doesn't exists */
19979                                 con->http_status = 404;
19980 -                               
19981 +
19982                                 if (con->conf.log_file_not_found) {
19983                                         log_error_write(srv, __FILE__, __LINE__, "sbsb",
19984                                                         "file not found:", con->uri.path,
19985                                                         "->", con->physical.path);
19986                                 }
19987 -                               
19988 +
19989                                 buffer_reset(con->physical.path);
19990 -                               
19991 +
19992                                 return HANDLER_FINISHED;
19993                         }
19994 -                       
19995 +
19996                         /* we have a PATHINFO */
19997                         if (pathinfo) {
19998                                 buffer_copy_string(con->request.pathinfo, pathinfo);
19999 -                               
20000 +
20001                                 /*
20002                                  * shorten uri.path
20003                                  */
20004 -                               
20005 +
20006                                 con->uri.path->used -= strlen(pathinfo);
20007                                 con->uri.path->ptr[con->uri.path->used - 1] = '\0';
20008                         }
20009 -                       
20010 +
20011                         if (con->conf.log_request_handling) {
20012                                 log_error_write(srv, __FILE__, __LINE__,  "s",  "-- after pathinfo check");
20013                                 log_error_write(srv, __FILE__, __LINE__,  "sb", "Path         :", con->physical.path);
20014 @@ -577,12 +590,12 @@
20015                                 log_error_write(srv, __FILE__, __LINE__,  "sb", "Pathinfo     :", con->request.pathinfo);
20016                         }
20017                 }
20018 -               
20019 +
20020                 if (con->conf.log_request_handling) {
20021                         log_error_write(srv, __FILE__, __LINE__,  "s",  "-- handling subrequest");
20022                         log_error_write(srv, __FILE__, __LINE__,  "sb", "Path         :", con->physical.path);
20023                 }
20024 -               
20025 +
20026                 /* call the handlers */
20027                 switch(r = plugins_call_handle_subrequest_start(srv, con)) {
20028                 case HANDLER_GO_ON:
20029 @@ -593,32 +606,32 @@
20030                         if (con->conf.log_request_handling) {
20031                                 log_error_write(srv, __FILE__, __LINE__,  "s",  "-- subrequest finished");
20032                         }
20033 -                       
20034 -                       /* something strange happend */
20035 +
20036 +                       /* something strange happened */
20037                         return r;
20038                 }
20039 -               
20040 -               /* if we are still here, no one wanted the file, status 403 is ok I think */
20041 -               
20042 +
20043 +               /* if we are still here, no one wanted the file; status 403 is ok I think */
20044 +
20045                 if (con->mode == DIRECT) {
20046                         con->http_status = 403;
20047 -                       
20048 +
20049                         return HANDLER_FINISHED;
20050                 }
20051 -               
20052 +
20053         }
20054 -       
20055 +
20056         switch(r = plugins_call_handle_subrequest(srv, con)) {
20057         case HANDLER_GO_ON:
20058 -               /* request was not handled, looks like we are done */
20059 +               /* request was not handled; looks like we are done */
20060                 return HANDLER_FINISHED;
20061         case HANDLER_FINISHED:
20062                 /* request is finished */
20063         default:
20064 -               /* something strange happend */
20065 +               /* something strange happened */
20066                 return r;
20067         }
20068 -       
20069 +
20070         /* can't happen */
20071         return HANDLER_COMEBACK;
20072  }
20073
20074 Property changes on: src/response.c
20075 ___________________________________________________________________
20076 Name: svn:eol-style
20077    + native
20078
20079 Index: src/plugin.c
20080 ===================================================================
20081 --- src/plugin.c        (.../tags/lighttpd-1.4.11)      (revision 1159)
20082 +++ src/plugin.c        (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
20083 @@ -13,27 +13,27 @@
20084  #include <valgrind/valgrind.h>
20085  #endif
20086  
20087 -#ifndef __WIN32
20088 +#ifndef _WIN32
20089  #include <dlfcn.h>
20090  #endif
20091  /*
20092 - * 
20093 + *
20094   * if you change this enum to add a new callback, be sure
20095   * - that PLUGIN_FUNC_SIZEOF is the last entry
20096   * - that you add PLUGIN_TO_SLOT twice:
20097 - *   1. as callback-dispatcher 
20098 + *   1. as callback-dispatcher
20099   *   2. in plugins_call_init()
20100 - * 
20101 + *
20102   */
20103  
20104  typedef struct {
20105         PLUGIN_DATA;
20106  } plugin_data;
20107  
20108 -typedef enum { 
20109 +typedef enum {
20110         PLUGIN_FUNC_UNSET,
20111 -               PLUGIN_FUNC_HANDLE_URI_CLEAN, 
20112 -               PLUGIN_FUNC_HANDLE_URI_RAW, 
20113 +               PLUGIN_FUNC_HANDLE_URI_CLEAN,
20114 +               PLUGIN_FUNC_HANDLE_URI_RAW,
20115                 PLUGIN_FUNC_HANDLE_REQUEST_DONE,
20116                 PLUGIN_FUNC_HANDLE_CONNECTION_CLOSE,
20117                 PLUGIN_FUNC_HANDLE_TRIGGER,
20118 @@ -44,38 +44,42 @@
20119                 PLUGIN_FUNC_HANDLE_DOCROOT,
20120                 PLUGIN_FUNC_HANDLE_PHYSICAL,
20121                 PLUGIN_FUNC_CONNECTION_RESET,
20122 -               PLUGIN_FUNC_INIT, 
20123 +               PLUGIN_FUNC_INIT,
20124                 PLUGIN_FUNC_CLEANUP,
20125                 PLUGIN_FUNC_SET_DEFAULTS,
20126 -               
20127 +
20128                 PLUGIN_FUNC_SIZEOF
20129  } plugin_t;
20130  
20131  static plugin *plugin_init(void) {
20132         plugin *p;
20133 -       
20134 +
20135         p = calloc(1, sizeof(*p));
20136 -       
20137 +
20138 +       p->required_plugins = array_init();
20139 +
20140         return p;
20141  }
20142  
20143  static void plugin_free(plugin *p) {
20144         int use_dlclose = 1;
20145         if (p->name) buffer_free(p->name);
20146 +
20147 +       array_free(p->required_plugins);
20148  #ifdef HAVE_VALGRIND_VALGRIND_H
20149         /*if (RUNNING_ON_VALGRIND) use_dlclose = 0;*/
20150  #endif
20151  
20152  #ifndef LIGHTTPD_STATIC
20153 -       if (use_dlclose && p->lib) {    
20154 -#ifdef __WIN32
20155 +       if (use_dlclose && p->lib) {
20156 +#ifdef _WIN32
20157                 FreeLibrary(p->lib);
20158  #else
20159                 dlclose(p->lib);
20160  #endif
20161         }
20162  #endif
20163 -               
20164 +
20165         free(p);
20166  }
20167  
20168 @@ -89,17 +93,17 @@
20169                 srv->plugins.size += 4;
20170                 srv->plugins.ptr   = realloc(srv->plugins.ptr, srv->plugins.size * sizeof(*ps));
20171         }
20172 -       
20173 +
20174         ps = srv->plugins.ptr;
20175         ps[srv->plugins.used++] = p;
20176 -       
20177 +
20178         return 0;
20179  }
20180  
20181  /**
20182 - * 
20183 - * 
20184 - * 
20185 + *
20186 + *
20187 + *
20188   */
20189  
20190  #ifdef LIGHTTPD_STATIC
20191 @@ -121,30 +125,35 @@
20192  #else
20193  int plugins_load(server *srv) {
20194         plugin *p;
20195 +#ifdef _WIN32
20196 +    FARPROC init;
20197 +#else
20198         int (*init)(plugin *pl);
20199 +#endif
20200 +
20201         const char *error;
20202 -       size_t i;
20203 -       
20204 +       size_t i, j, k;
20205 +
20206         for (i = 0; i < srv->srvconf.modules->used; i++) {
20207                 data_string *d = (data_string *)srv->srvconf.modules->data[i];
20208                 char *modules = d->value->ptr;
20209 -       
20210 +
20211                 buffer_copy_string_buffer(srv->tmp_buf, srv->srvconf.modules_dir);
20212  
20213                 buffer_append_string(srv->tmp_buf, "/");
20214                 buffer_append_string(srv->tmp_buf, modules);
20215 -#if defined(__WIN32) || defined(__CYGWIN__)
20216 +#if defined(_WIN32) || defined(__CYGWIN__)
20217                 buffer_append_string(srv->tmp_buf, ".dll");
20218  #else
20219                 buffer_append_string(srv->tmp_buf, ".so");
20220  #endif
20221 -       
20222 +
20223                 p = plugin_init();
20224 -#ifdef __WIN32
20225 +#ifdef _WIN32
20226                 if (NULL == (p->lib = LoadLibrary(srv->tmp_buf->ptr))) {
20227                         LPVOID lpMsgBuf;
20228                         FormatMessage(
20229 -                               FORMAT_MESSAGE_ALLOCATE_BUFFER | 
20230 +                               FORMAT_MESSAGE_ALLOCATE_BUFFER |
20231                                 FORMAT_MESSAGE_FROM_SYSTEM,
20232                                 NULL,
20233                                 GetLastError(),
20234 @@ -152,36 +161,36 @@
20235                                 (LPTSTR) &lpMsgBuf,
20236                                 0, NULL );
20237  
20238 -                       log_error_write(srv, __FILE__, __LINE__, "ssb", "LoadLibrary() failed", 
20239 +                       log_error_write(srv, __FILE__, __LINE__, "ssb", "LoadLibrary() failed",
20240                                         lpMsgBuf, srv->tmp_buf);
20241 -                       
20242 +
20243                         plugin_free(p);
20244 -                       
20245 +
20246                         return -1;
20247  
20248                 }
20249 -#else  
20250 +#else
20251                 if (NULL == (p->lib = dlopen(srv->tmp_buf->ptr, RTLD_LAZY))) {
20252 -                       log_error_write(srv, __FILE__, __LINE__, "sbs", "dlopen() failed for:", 
20253 +                       log_error_write(srv, __FILE__, __LINE__, "sbs", "dlopen() failed for:",
20254                                         srv->tmp_buf, dlerror());
20255 -                       
20256 +
20257                         plugin_free(p);
20258 -                       
20259 +
20260                         return -1;
20261                 }
20262 -               
20263 +
20264  #endif
20265                 buffer_reset(srv->tmp_buf);
20266                 buffer_copy_string(srv->tmp_buf, modules);
20267                 buffer_append_string(srv->tmp_buf, "_plugin_init");
20268  
20269 -#ifdef __WIN32
20270 +#ifdef _WIN32
20271                 init = GetProcAddress(p->lib, srv->tmp_buf->ptr);
20272  
20273                 if (init == NULL)  {
20274                         LPVOID lpMsgBuf;
20275                         FormatMessage(
20276 -                               FORMAT_MESSAGE_ALLOCATE_BUFFER | 
20277 +                               FORMAT_MESSAGE_ALLOCATE_BUFFER |
20278                                 FORMAT_MESSAGE_FROM_SYSTEM,
20279                                 NULL,
20280                                 GetLastError(),
20281 @@ -190,7 +199,7 @@
20282                                 0, NULL );
20283  
20284                         log_error_write(srv, __FILE__, __LINE__, "sbs", "getprocaddress failed:", srv->tmp_buf, lpMsgBuf);
20285 -                       
20286 +
20287                         plugin_free(p);
20288                         return -1;
20289                 }
20290 @@ -203,24 +212,43 @@
20291  #endif
20292                 if ((error = dlerror()) != NULL)  {
20293                         log_error_write(srv, __FILE__, __LINE__, "s", error);
20294 -                       
20295 +
20296                         plugin_free(p);
20297                         return -1;
20298                 }
20299 -       
20300 +
20301  #endif
20302                 if ((*init)(p)) {
20303                         log_error_write(srv, __FILE__, __LINE__, "ss", modules, "plugin init failed" );
20304 -                       
20305 +
20306                         plugin_free(p);
20307                         return -1;
20308                 }
20309  #if 0
20310                 log_error_write(srv, __FILE__, __LINE__, "ss", modules, "plugin loaded" );
20311  #endif
20312 +               /* check if the required plugin is loaded */
20313 +               for (k = 0; k < p->required_plugins->used; k++) {
20314 +                       data_string *req = (data_string *)p->required_plugins->data[k];
20315 +
20316 +                       for (j = 0; j < i; j++) {
20317 +                               data_string *mod = (data_string *)srv->srvconf.modules->data[j];
20318 +
20319 +                               if (buffer_is_equal(req->value, mod->value)) break;
20320 +                       }
20321 +
20322 +                       if (j == i) {
20323 +                               /* not found */
20324 +                               log_error_write(srv, __FILE__, __LINE__, "ssbs", modules, "failed to load. required plugin", req->value, "was not loaded" );
20325 +
20326 +                               plugin_free(p);
20327 +                       
20328 +                               return -1;
20329 +                       }
20330 +               }
20331                 plugins_register(srv, p);
20332         }
20333 -       
20334 +
20335         return 0;
20336  }
20337  #endif
20338 @@ -253,8 +281,8 @@
20339         }
20340  
20341  /**
20342 - * plugins that use 
20343 - * 
20344 + * plugins that use
20345 + *
20346   * - server *srv
20347   * - connection *con
20348   * - void *p_d (plugin_data *)
20349 @@ -301,12 +329,12 @@
20350         }
20351  
20352  /**
20353 - * plugins that use 
20354 - * 
20355 + * plugins that use
20356 + *
20357   * - server *srv
20358   * - void *p_d (plugin_data *)
20359   */
20360 -                                                                       
20361 +
20362  PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_TRIGGER, handle_trigger)
20363  PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_SIGHUP, handle_sighup)
20364  PLUGIN_TO_SLOT(PLUGIN_FUNC_CLEANUP, cleanup)
20365 @@ -314,18 +342,18 @@
20366  
20367  #undef PLUGIN_TO_SLOT
20368  
20369 -#if 0                                                                  
20370 +#if 0
20371  /**
20372 - * 
20373 + *
20374   * special handler
20375 - * 
20376 + *
20377   */
20378  handler_t plugins_call_handle_fdevent(server *srv, const fd_conn *fdc) {
20379         size_t i;
20380         plugin **ps;
20381 -       
20382 +
20383         ps = srv->plugins.ptr;
20384 -       
20385 +
20386         for (i = 0; i < srv->plugins.used; i++) {
20387                 plugin *p = ps[i];
20388                 if (p->handle_fdevent) {
20389 @@ -344,34 +372,34 @@
20390                         }
20391                 }
20392         }
20393 -       
20394 +
20395         return HANDLER_GO_ON;
20396  }
20397  #endif
20398  /**
20399 - * 
20400 + *
20401   * - call init function of all plugins to init the plugin-internals
20402   * - added each plugin that supports has callback to the corresponding slot
20403 - * 
20404 + *
20405   * - is only called once.
20406   */
20407  
20408  handler_t plugins_call_init(server *srv) {
20409         size_t i;
20410         plugin **ps;
20411 -       
20412 +
20413         ps = srv->plugins.ptr;
20414 -       
20415 +
20416         /* fill slots */
20417 -       
20418 +
20419         srv->plugin_slots = calloc(PLUGIN_FUNC_SIZEOF, sizeof(ps));
20420 -       
20421 +
20422         for (i = 0; i < srv->plugins.used; i++) {
20423                 size_t j;
20424                 /* check which calls are supported */
20425 -               
20426 +
20427                 plugin *p = ps[i];
20428 -               
20429 +
20430  #define PLUGIN_TO_SLOT(x, y) \
20431         if (p->y) { \
20432                 plugin **slot = ((plugin ***)(srv->plugin_slots))[x]; \
20433 @@ -384,11 +412,11 @@
20434                         slot[j] = p;\
20435                         break;\
20436                 }\
20437 -       } 
20438 -               
20439 -               
20440 -               PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_CLEAN, handle_uri_clean); 
20441 -               PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_RAW, handle_uri_raw); 
20442 +       }
20443 +
20444 +
20445 +               PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_CLEAN, handle_uri_clean);
20446 +               PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_URI_RAW, handle_uri_raw);
20447                 PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_REQUEST_DONE, handle_request_done);
20448                 PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_CONNECTION_CLOSE, handle_connection_close);
20449                 PLUGIN_TO_SLOT(PLUGIN_FUNC_HANDLE_TRIGGER, handle_trigger);
20450 @@ -402,19 +430,19 @@
20451                 PLUGIN_TO_SLOT(PLUGIN_FUNC_CLEANUP, cleanup);
20452                 PLUGIN_TO_SLOT(PLUGIN_FUNC_SET_DEFAULTS, set_defaults);
20453  #undef PLUGIN_TO_SLOT
20454 -               
20455 +
20456                 if (p->init) {
20457                         if (NULL == (p->data = p->init())) {
20458 -                               log_error_write(srv, __FILE__, __LINE__, "sb", 
20459 +                               log_error_write(srv, __FILE__, __LINE__, "sb",
20460                                                 "plugin-init failed for module", p->name);
20461                                 return HANDLER_ERROR;
20462                         }
20463 -                       
20464 +
20465                         /* used for con->mode, DIRECT == 0, plugins above that */
20466                         ((plugin_data *)(p->data))->id = i + 1;
20467 -                       
20468 +
20469                         if (p->version != LIGHTTPD_VERSION_ID) {
20470 -                               log_error_write(srv, __FILE__, __LINE__, "sb", 
20471 +                               log_error_write(srv, __FILE__, __LINE__, "sb",
20472                                                 "plugin-version doesn't match lighttpd-version for", p->name);
20473                                 return HANDLER_ERROR;
20474                         }
20475 @@ -422,29 +450,46 @@
20476                         p->data = NULL;
20477                 }
20478         }
20479 -       
20480 +
20481         return HANDLER_GO_ON;
20482  }
20483  
20484 +/**
20485 + * get the config-storage of the named plugin 
20486 + */
20487 +void *plugin_get_config(server *srv, const char *name) {
20488 +       size_t i;
20489 +
20490 +       for (i = 0; i < srv->plugins.used; i++) {
20491 +               plugin *p = ((plugin **)srv->plugins.ptr)[i];
20492 +
20493 +               if (buffer_is_equal_string(p->name, name, strlen(name))) {
20494 +                       return p->data;
20495 +               }
20496 +       }
20497 +
20498 +       return NULL;
20499 +}
20500 +
20501  void plugins_free(server *srv) {
20502         size_t i;
20503         plugins_call_cleanup(srv);
20504 -       
20505 +
20506         for (i = 0; i < srv->plugins.used; i++) {
20507                 plugin *p = ((plugin **)srv->plugins.ptr)[i];
20508 -               
20509 +
20510                 plugin_free(p);
20511         }
20512 -       
20513 +
20514         for (i = 0; srv->plugin_slots && i < PLUGIN_FUNC_SIZEOF; i++) {
20515                 plugin **slot = ((plugin ***)(srv->plugin_slots))[i];
20516 -               
20517 +
20518                 if (slot) free(slot);
20519         }
20520 -       
20521 +
20522         free(srv->plugin_slots);
20523         srv->plugin_slots = NULL;
20524 -       
20525 +
20526         free(srv->plugins.ptr);
20527         srv->plugins.ptr = NULL;
20528         srv->plugins.used = 0;
20529
20530 Property changes on: src/plugin.c
20531 ___________________________________________________________________
20532 Name: svn:eol-style
20533    + native
20534
20535 Index: src/stat_cache.c
20536 ===================================================================
20537 --- src/stat_cache.c    (.../tags/lighttpd-1.4.11)      (revision 1159)
20538 +++ src/stat_cache.c    (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
20539 @@ -6,7 +6,6 @@
20540  #include <stdlib.h>
20541  #include <string.h>
20542  #include <errno.h>
20543 -#include <unistd.h>
20544  #include <stdio.h>
20545  #include <fcntl.h>
20546  #include <assert.h>
20547 @@ -25,20 +24,9 @@
20548  #endif
20549  
20550  #include "sys-mmap.h"
20551 +#include "sys-files.h"
20552 +#include "sys-strings.h"
20553  
20554 -/* NetBSD 1.3.x needs it */
20555 -#ifndef MAP_FAILED
20556 -# define MAP_FAILED -1
20557 -#endif
20558 -
20559 -#ifndef O_LARGEFILE
20560 -# define O_LARGEFILE 0
20561 -#endif
20562 -
20563 -#ifndef HAVE_LSTAT
20564 -#define lstat stat
20565 -#endif
20566 -
20567  #if 0
20568  /* enables debug code for testing if all nodes in the stat-cache as accessable */
20569  #define DEBUG_STAT_CACHE
20570 @@ -52,8 +40,8 @@
20571   *
20572   * if we get a change-event from FAM, we increment the version in the FAM->dir mapping
20573   *
20574 - * if the stat()-cache is queried we check if the version id for the directory is the 
20575 - * same and return immediatly. 
20576 + * if the stat()-cache is queried we check if the version id for the directory is the
20577 + * same and return immediatly.
20578   *
20579   *
20580   * What we need:
20581 @@ -62,17 +50,17 @@
20582   * - for each FAMRequest we have to find the version in the directory cache (index as userdata)
20583   *
20584   * stat <<-> directory <-> FAMRequest
20585 - * 
20586 - * if file is deleted, directory is dirty, file is rechecked ... 
20587 + *
20588 + * if file is deleted, directory is dirty, file is rechecked ...
20589   * if directory is deleted, directory mapping is removed
20590 - *  
20591 + *
20592   * */
20593  
20594  #ifdef HAVE_FAM_H
20595  typedef struct {
20596         FAMRequest *req;
20597         FAMConnection *fc;
20598 -       
20599 +
20600         buffer *name;
20601  
20602         int version;
20603 @@ -83,16 +71,16 @@
20604   * - we need a hash
20605   * - the hash-key is used as sorting criteria for a tree
20606   * - a splay-tree is used as we can use the caching effect of it
20607 - */ 
20608 + */
20609  
20610  /* we want to cleanup the stat-cache every few seconds, let's say 10
20611   *
20612   * - remove entries which are outdated since 30s
20613   * - remove entries which are fresh but havn't been used since 60s
20614   * - if we don't have a stat-cache entry for a directory, release it from the monitor
20615 - */ 
20616 + */
20617  
20618 -#ifdef DEBUG_STAT_CACHE        
20619 +#ifdef DEBUG_STAT_CACHE
20620  typedef struct {
20621         int *ptr;
20622  
20623 @@ -105,15 +93,15 @@
20624  
20625  stat_cache *stat_cache_init(void) {
20626         stat_cache *fc = NULL;
20627 -       
20628 +
20629         fc = calloc(1, sizeof(*fc));
20630 -       
20631 +
20632         fc->dir_name = buffer_init();
20633  #ifdef HAVE_FAM_H
20634         fc->fam = calloc(1, sizeof(*fc->fam));
20635  #endif
20636  
20637 -#ifdef DEBUG_STAT_CACHE        
20638 +#ifdef DEBUG_STAT_CACHE
20639         ctrl.size = 0;
20640  #endif
20641  
20642 @@ -122,24 +110,24 @@
20643  
20644  static stat_cache_entry * stat_cache_entry_init(void) {
20645         stat_cache_entry *sce = NULL;
20646 -       
20647 +
20648         sce = calloc(1, sizeof(*sce));
20649 -       
20650 +
20651         sce->name = buffer_init();
20652         sce->etag = buffer_init();
20653         sce->content_type = buffer_init();
20654 -       
20655 +
20656         return sce;
20657  }
20658  
20659  static void stat_cache_entry_free(void *data) {
20660         stat_cache_entry *sce = data;
20661         if (!sce) return;
20662 -       
20663 +
20664         buffer_free(sce->etag);
20665         buffer_free(sce->name);
20666         buffer_free(sce->content_type);
20667 -       
20668 +
20669         free(sce);
20670  }
20671  
20672 @@ -148,22 +136,22 @@
20673         fam_dir_entry *fam_dir = NULL;
20674  
20675         fam_dir = calloc(1, sizeof(*fam_dir));
20676 -       
20677 +
20678         fam_dir->name = buffer_init();
20679 -       
20680 +
20681         return fam_dir;
20682  }
20683  
20684  static void fam_dir_entry_free(void *data) {
20685         fam_dir_entry *fam_dir = data;
20686 -       
20687 +
20688         if (!fam_dir) return;
20689 -       
20690 +
20691         FAMCancelMonitor(fam_dir->fc, fam_dir->req);
20692 -       
20693 +
20694         buffer_free(fam_dir->name);
20695         free(fam_dir->req);
20696 -       
20697 +
20698         free(fam_dir);
20699  }
20700  #endif
20701 @@ -174,7 +162,7 @@
20702                 splay_tree *node = sc->files;
20703  
20704                 osize = sc->files->size;
20705 -                       
20706 +
20707                 stat_cache_entry_free(node->data);
20708                 sc->files = splaytree_delete(sc->files, node->key);
20709  
20710 @@ -187,12 +175,12 @@
20711         while (sc->dirs) {
20712                 int osize;
20713                 splay_tree *node = sc->dirs;
20714 -               
20715 +
20716                 osize = sc->dirs->size;
20717  
20718                 fam_dir_entry_free(node->data);
20719                 sc->dirs = splaytree_delete(sc->dirs, node->key);
20720 -               
20721 +
20722                 if (osize == 1) {
20723                         assert(NULL == sc->dirs);
20724                 } else {
20725 @@ -212,7 +200,7 @@
20726  static int stat_cache_attr_get(buffer *buf, char *name) {
20727         int attrlen;
20728         int ret;
20729 -       
20730 +
20731         attrlen = 1024;
20732         buffer_prepare_copy(buf, attrlen);
20733         attrlen--;
20734 @@ -251,15 +239,15 @@
20735             sc->fam) {
20736  
20737                 events = FAMPending(sc->fam);
20738 -       
20739 +
20740                 for (i = 0; i < events; i++) {
20741                         FAMEvent fe;
20742                         fam_dir_entry *fam_dir;
20743                         splay_tree *node;
20744                         int ndx;
20745 -               
20746 +
20747                         FAMNextEvent(sc->fam, &fe);
20748 -       
20749 +
20750                         /* handle event */
20751  
20752                         switch(fe.code) {
20753 @@ -280,7 +268,7 @@
20754  
20755                                 sc->dirs = splaytree_splay(sc->dirs, ndx);
20756                                 node = sc->dirs;
20757 -                       
20758 +
20759                                 if (node && (node->key == ndx)) {
20760                                         int osize = splaytree_size(sc->dirs);
20761  
20762 @@ -308,7 +296,7 @@
20763  
20764                 sc->fam = NULL;
20765         }
20766 -       
20767 +
20768         return HANDLER_GO_ON;
20769  }
20770  
20771 @@ -332,7 +320,7 @@
20772   *
20773   *
20774   *
20775 - * returns: 
20776 + * returns:
20777   *  - HANDLER_FINISHED on cache-miss (don't forget to reopen the file)
20778   *  - HANDLER_ERROR on stat() failed -> see errno for problem
20779   */
20780 @@ -348,16 +336,16 @@
20781         struct stat st;
20782         size_t k;
20783         int fd;
20784 -#ifdef DEBUG_STAT_CACHE        
20785 +#ifdef DEBUG_STAT_CACHE
20786         size_t i;
20787  #endif
20788  
20789         int file_ndx;
20790         splay_tree *file_node = NULL;
20791  
20792 -       *ret_sce = NULL; 
20793 +       *ret_sce = NULL;
20794  
20795 -       /* 
20796 +       /*
20797          * check if the directory for this file has changed
20798          */
20799  
20800 @@ -366,23 +354,23 @@
20801         file_ndx = hashme(name);
20802         sc->files = splaytree_splay(sc->files, file_ndx);
20803  
20804 -#ifdef DEBUG_STAT_CACHE        
20805 +#ifdef DEBUG_STAT_CACHE
20806         for (i = 0; i < ctrl.used; i++) {
20807                 if (ctrl.ptr[i] == file_ndx) break;
20808         }
20809  #endif
20810  
20811         if (sc->files && (sc->files->key == file_ndx)) {
20812 -#ifdef DEBUG_STAT_CACHE        
20813 +#ifdef DEBUG_STAT_CACHE
20814                 /* it was in the cache */
20815                 assert(i < ctrl.used);
20816  #endif
20817 -               
20818 -               /* we have seen this file already and 
20819 +
20820 +               /* we have seen this file already and
20821                  * don't stat() it again in the same second */
20822  
20823                 file_node = sc->files;
20824 -               
20825 +
20826                 sce = file_node->data;
20827  
20828                 /* check if the name is the same, we might have a collision */
20829 @@ -390,7 +378,7 @@
20830                 if (buffer_is_equal(name, sce->name)) {
20831                         if (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_SIMPLE) {
20832                                 if (sce->stat_ts == srv->cur_ts) {
20833 -                                       *ret_sce = sce; 
20834 +                                       *ret_sce = sce;
20835                                         return HANDLER_GO_ON;
20836                                 }
20837                         }
20838 @@ -400,15 +388,15 @@
20839                          * file_node is used by the FAM check below to see if we know this file
20840                          * and if we can save a stat().
20841                          *
20842 -                        * BUT, the sce is not reset here as the entry into the cache is ok, we 
20843 +                        * BUT, the sce is not reset here as the entry into the cache is ok, we
20844                          * it is just not pointing to our requested file.
20845 -                        * 
20846 +                        *
20847                          *  */
20848  
20849                         file_node = NULL;
20850                 }
20851         } else {
20852 -#ifdef DEBUG_STAT_CACHE        
20853 +#ifdef DEBUG_STAT_CACHE
20854                 if (i != ctrl.used) {
20855                         fprintf(stderr, "%s.%d: %08x was already inserted but not found in cache, %s\n", __FILE__, __LINE__, file_ndx, name->ptr);
20856                 }
20857 @@ -424,23 +412,23 @@
20858                 }
20859  
20860                 dir_ndx = hashme(sc->dir_name);
20861 -               
20862 +
20863                 sc->dirs = splaytree_splay(sc->dirs, dir_ndx);
20864 -               
20865 +
20866                 if (sc->dirs && (sc->dirs->key == dir_ndx)) {
20867                         dir_node = sc->dirs;
20868                 }
20869 -               
20870 +
20871                 if (dir_node && file_node) {
20872                         /* we found a file */
20873 -                       
20874 +
20875                         sce = file_node->data;
20876                         fam_dir = dir_node->data;
20877 -                       
20878 +
20879                         if (fam_dir->version == sce->dir_version) {
20880                                 /* the stat()-cache entry is still ok */
20881 -                               
20882 -                               *ret_sce = sce; 
20883 +
20884 +                               *ret_sce = sce;
20885                                 return HANDLER_GO_ON;
20886                         }
20887                 }
20888 @@ -448,7 +436,7 @@
20889  #endif
20890  
20891         /*
20892 -        * *lol* 
20893 +        * *lol*
20894          * - open() + fstat() on a named-pipe results in a (intended) hang.
20895          * - stat() if regualar file + open() to see if we can read from it is better
20896          *
20897 @@ -469,16 +457,16 @@
20898  
20899         if (NULL == sce) {
20900                 int osize = 0;
20901 -                      
20902 +
20903                 if (sc->files) {
20904                         osize = sc->files->size;
20905                 }
20906  
20907                 sce = stat_cache_entry_init();
20908                 buffer_copy_string_buffer(sce->name, name);
20909 -               
20910 -               sc->files = splaytree_insert(sc->files, file_ndx, sce); 
20911 -#ifdef DEBUG_STAT_CACHE        
20912 +
20913 +               sc->files = splaytree_insert(sc->files, file_ndx, sce);
20914 +#ifdef DEBUG_STAT_CACHE
20915                 if (ctrl.size == 0) {
20916                         ctrl.size = 16;
20917                         ctrl.used = 0;
20918 @@ -499,29 +487,29 @@
20919         sce->st = st;
20920         sce->stat_ts = srv->cur_ts;
20921  
20922 -       /* catch the obvious symlinks 
20923 +       /* catch the obvious symlinks
20924          *
20925          * this is not a secure check as we still have a race-condition between
20926 -        * the stat() and the open. We can only solve this by 
20927 +        * the stat() and the open. We can only solve this by
20928          * 1. open() the file
20929          * 2. fstat() the fd
20930          *
20931          * and keeping the file open for the rest of the time. But this can
20932          * only be done at network level.
20933 -        * 
20934 +        *
20935          * */
20936         if (S_ISLNK(st.st_mode) && !con->conf.follow_symlink) {
20937                 return HANDLER_ERROR;
20938         }
20939  
20940 -       if (S_ISREG(st.st_mode)) {      
20941 +       if (S_ISREG(st.st_mode)) {
20942                 /* determine mimetype */
20943                 buffer_reset(sce->content_type);
20944 -               
20945 +
20946                 for (k = 0; k < con->conf.mimetypes->used; k++) {
20947                         data_string *ds = (data_string *)con->conf.mimetypes->data[k];
20948                         buffer *type = ds->key;
20949 -               
20950 +
20951                         if (type->used == 0) continue;
20952  
20953                         /* check if the right side is the same */
20954 @@ -539,7 +527,7 @@
20955                 }
20956  #endif
20957         }
20958 -               
20959 +
20960  #ifdef HAVE_FAM_H
20961         if (sc->fam &&
20962             (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_FAM)) {
20963 @@ -549,19 +537,19 @@
20964                         fam_dir->fc = sc->fam;
20965  
20966                         buffer_copy_string_buffer(fam_dir->name, sc->dir_name);
20967 -                       
20968 +
20969                         fam_dir->version = 1;
20970 -                       
20971 +
20972                         fam_dir->req = calloc(1, sizeof(FAMRequest));
20973 -                       
20974 -                       if (0 != FAMMonitorDirectory(sc->fam, fam_dir->name->ptr, 
20975 +
20976 +                       if (0 != FAMMonitorDirectory(sc->fam, fam_dir->name->ptr,
20977                                                      fam_dir->req, fam_dir)) {
20978 -                               
20979 -                               log_error_write(srv, __FILE__, __LINE__, "sbs", 
20980 -                                               "monitoring dir failed:", 
20981 -                                               fam_dir->name, 
20982 +
20983 +                               log_error_write(srv, __FILE__, __LINE__, "sbs",
20984 +                                               "monitoring dir failed:",
20985 +                                               fam_dir->name,
20986                                                 FamErrlist[FAMErrno]);
20987 -                               
20988 +
20989                                 fam_dir_entry_free(fam_dir);
20990                         } else {
20991                                 int osize = 0;
20992 @@ -570,7 +558,7 @@
20993                                         osize = sc->dirs->size;
20994                                 }
20995  
20996 -                               sc->dirs = splaytree_insert(sc->dirs, dir_ndx, fam_dir); 
20997 +                               sc->dirs = splaytree_insert(sc->dirs, dir_ndx, fam_dir);
20998                                 assert(sc->dirs);
20999                                 assert(sc->dirs->data == fam_dir);
21000                                 assert(osize == (sc->dirs->size - 1));
21001 @@ -578,9 +566,9 @@
21002                 } else {
21003                         fam_dir = dir_node->data;
21004                 }
21005 -               
21006 +
21007                 /* bind the fam_fc to the stat() cache entry */
21008 -                       
21009 +
21010                 if (fam_dir) {
21011                         sce->dir_version = fam_dir->version;
21012                         sce->dir_ndx     = dir_ndx;
21013 @@ -594,11 +582,11 @@
21014  }
21015  
21016  /**
21017 - * remove stat() from cache which havn't been stat()ed for 
21018 + * remove stat() from cache which havn't been stat()ed for
21019   * more than 10 seconds
21020 - * 
21021   *
21022 - * walk though the stat-cache, collect the ids which are too old 
21023 + *
21024 + * walk though the stat-cache, collect the ids which are too old
21025   * and remove them in a second loop
21026   */
21027  
21028 @@ -639,9 +627,9 @@
21029                 sc->files = splaytree_splay(sc->files, ndx);
21030  
21031                 node = sc->files;
21032 -               
21033 +
21034                 if (node && (node->key == ndx)) {
21035 -#ifdef DEBUG_STAT_CACHE        
21036 +#ifdef DEBUG_STAT_CACHE
21037                         size_t j;
21038                         int osize = splaytree_size(sc->files);
21039                         stat_cache_entry *sce = node->data;
21040 @@ -649,7 +637,7 @@
21041                         stat_cache_entry_free(node->data);
21042                         sc->files = splaytree_delete(sc->files, ndx);
21043  
21044 -#ifdef DEBUG_STAT_CACHE        
21045 +#ifdef DEBUG_STAT_CACHE
21046                         for (j = 0; j < ctrl.used; j++) {
21047                                 if (ctrl.ptr[j] == ndx) {
21048                                         ctrl.ptr[j] = ctrl.ptr[--ctrl.used];
21049
21050 Property changes on: src/stat_cache.c
21051 ___________________________________________________________________
21052 Name: svn:eol-style
21053    + native
21054
21055 Index: src/sys-process.h
21056 ===================================================================
21057 --- src/sys-process.h   (.../tags/lighttpd-1.4.11)      (revision 0)
21058 +++ src/sys-process.h   (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
21059 @@ -0,0 +1,17 @@
21060 +#ifndef _SYS_PROCESS_H_
21061 +#define _SYS_PROCESS_H_
21062 +
21063 +#ifdef _WIN32
21064 +#include <process.h>
21065 +#define pid_t int
21066 +/* win32 has no fork() */
21067 +#define kill(x, y)
21068 +#define getpid() 0
21069 +
21070 +#else
21071 +#include <sys/wait.h>
21072 +#include <unistd.h>
21073 +#endif
21074 +
21075 +#endif
21076 +
21077
21078 Property changes on: src/sys-process.h
21079 ___________________________________________________________________
21080 Name: svn:eol-style
21081    + native
21082
21083 Index: src/mod_ssi_expr.h
21084 ===================================================================
21085 --- src/mod_ssi_expr.h  (.../tags/lighttpd-1.4.11)      (revision 1159)
21086 +++ src/mod_ssi_expr.h  (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
21087 @@ -5,16 +5,16 @@
21088  
21089  typedef struct {
21090         enum { SSI_TYPE_UNSET, SSI_TYPE_BOOL, SSI_TYPE_STRING } type;
21091 -       
21092 +
21093         buffer *str;
21094         int     bo;
21095  } ssi_val_t;
21096  
21097  typedef struct {
21098         int     ok;
21099 -       
21100 +
21101         ssi_val_t val;
21102 -       
21103 +
21104         void   *srv;
21105  } ssi_ctx_t;
21106  
21107
21108 Property changes on: src/mod_ssi_expr.h
21109 ___________________________________________________________________
21110 Name: svn:eol-style
21111    + native
21112
21113 Index: src/plugin.h
21114 ===================================================================
21115 --- src/plugin.h        (.../tags/lighttpd-1.4.11)      (revision 1159)
21116 +++ src/plugin.h        (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
21117 @@ -12,6 +12,12 @@
21118  
21119  #define INIT_FUNC(x) \
21120                 static void *x()
21121 +/*
21122 + * The PATCH_OPTION() macro is used in the patch_connection() functions
21123 + * of the modules to update the config object for the current request.
21124 + */
21125 +#define PATCH_OPTION(x) \
21126 +               p->conf.x = s->x
21127  
21128  #define FREE_FUNC          SERVER_FUNC
21129  #define TRIGGER_FUNC       SERVER_FUNC
21130 @@ -25,19 +31,19 @@
21131  #define URIHANDLER_FUNC    CONNECTION_FUNC
21132  
21133  #define PLUGIN_DATA        size_t id
21134 -                                                                                                                                               
21135 +
21136  typedef struct {
21137         size_t version;
21138 -       
21139 +
21140         buffer *name; /* name of the plugin */
21141 -       
21142 +
21143         void *(* init)                       ();
21144         handler_t (* set_defaults)           (server *srv, void *p_d);
21145         handler_t (* cleanup)                (server *srv, void *p_d);
21146                                                                                            /* is called ... */
21147         handler_t (* handle_trigger)         (server *srv, void *p_d);                     /* once a second */
21148         handler_t (* handle_sighup)          (server *srv, void *p_d);                     /* at a signup */
21149 -       
21150 +
21151         handler_t (* handle_uri_raw)         (server *srv, connection *con, void *p_d);    /* after uri_raw is set */
21152         handler_t (* handle_uri_clean)       (server *srv, connection *con, void *p_d);    /* after uri is set */
21153         handler_t (* handle_docroot)         (server *srv, connection *con, void *p_d);    /* getting the document-root */
21154 @@ -45,20 +51,22 @@
21155         handler_t (* handle_request_done)    (server *srv, connection *con, void *p_d);    /* at the end of a request */
21156         handler_t (* handle_connection_close)(server *srv, connection *con, void *p_d);    /* at the end of a connection */
21157         handler_t (* handle_joblist)         (server *srv, connection *con, void *p_d);    /* after all events are handled */
21158 -       
21159 -       
21160 -       
21161 -       handler_t (* handle_subrequest_start)(server *srv, connection *con, void *p_d);   
21162 -       
21163 -                                                                                          /* when a handler for the request 
21164 +
21165 +
21166 +
21167 +       handler_t (* handle_subrequest_start)(server *srv, connection *con, void *p_d);
21168 +
21169 +                                                                                          /* when a handler for the request
21170                                                                                             * has to be found
21171                                                                                             */
21172         handler_t (* handle_subrequest)      (server *srv, connection *con, void *p_d);    /* */
21173         handler_t (* connection_reset)       (server *srv, connection *con, void *p_d);    /* */
21174         void *data;
21175 -       
21176 +
21177         /* dlopen handle */
21178         void *lib;
21179 +
21180 +       array *required_plugins;
21181  } plugin;
21182  
21183  int plugins_load(server *srv);
21184 @@ -88,5 +96,8 @@
21185  int config_patch_connection(server *srv, connection *con, comp_key_t comp);
21186  int config_check_cond(server *srv, connection *con, data_config *dc);
21187  int config_append_cond_match_buffer(connection *con, data_config *dc, buffer *buf, int n);
21188 +int config_exec_pcre_keyvalue_buffer(connection *con, pcre_keyvalue_buffer *kvb, data_config *context, buffer *match_buf, buffer *result);
21189  
21190 +void *plugin_get_config(server *srv, const char *name);
21191 +
21192  #endif
21193
21194 Property changes on: src/plugin.h
21195 ___________________________________________________________________
21196 Name: svn:eol-style
21197    + native
21198
21199
21200 Property changes on: src/stat_cache.h
21201 ___________________________________________________________________
21202 Name: svn:eol-style
21203    + native
21204
21205
21206 Property changes on: src/response.h
21207 ___________________________________________________________________
21208 Name: svn:eol-style
21209    + native
21210
21211 Index: src/SConscript
21212 ===================================================================
21213 --- src/SConscript      (.../tags/lighttpd-1.4.11)      (revision 1159)
21214 +++ src/SConscript      (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
21215 @@ -20,21 +20,49 @@
21216        http-header-glue.c \
21217        splaytree.c network_writev.c \
21218        network_write.c network_linux_sendfile.c \
21219 -      network_freebsd_sendfile.c  \
21220 +      network_freebsd_sendfile.c  network_win32_send.c \
21221        network_solaris_sendfilev.c network_openssl.c \
21222 -")
21223 +      http_resp.c http_resp_parser.c ")
21224        
21225 -src = Split("server.c response.c connections.c network.c \
21226 +src = Split("server.c response.c connections.c network.c sys-socket.c sys-files.c\
21227        configfile.c configparser.c request.c proc_open.c")
21228  
21229 +if re.compile("win32").search(env['PLATFORM']):
21230 +       src += [ 'getopt.c' ]
21231 +
21232  lemon = env.Program('lemon', 'lemon.c')
21233 +def lemonemitter(target, source, env):
21234 +       import os, SCons
21235 +       path = SCons.Util.to_String(target[0])
21236 +       base, ext = os.path.splitext(path)
21237 +       target += [ base + '.h' ]
21238  
21239 -configparser = env.Command(['configparser.c', 'configparser.h'], 'configparser.y', '(cd build; ../' + lemon[0].path + ' -q ../$SOURCE ../src/lempar.c; cd ..)')
21240 -env.Depends(configparser, lemon)
21241 +       # the hard way to workaround scons bug
21242 +       if os.path.exists(path) != os.path.exists(base + '.h'):
21243 +               if os.path.exists(path):
21244 +                       os.remove(path)
21245 +               else:
21246 +                       os.remove(base + '.h')
21247  
21248 -mod_ssi_exprparser = env.Command(['mod_ssi_exprparser.c', 'mod_ssi_exprparser.h'], 'mod_ssi_exprparser.y', '(cd build; ../' + lemon[0].path + ' -q ../$SOURCE ../src/lempar.c; cd ..)')
21249 -env.Depends(mod_ssi_exprparser, lemon)
21250 +       env.Depends(target, lemon)
21251 +       return (target, source)
21252  
21253 +if re.compile("win32").search(env['PLATFORM']):
21254 +       lemoncmd = '..\\' + lemon[0].path + ' -q ..\\$SOURCE ..\\src\\lempar.c || (del ..\\${TARGETS[0]} ..\\${TARGETS[1]} && exit 1)'
21255 +else:
21256 +       lemoncmd = '../' + lemon[0].path + ' -q ../$SOURCE ../src/lempar.c || (rm ../${TARGETS[0]} ../${TARGETS[1]} && exit 1)'
21257 +lemonbuilder = Builder(action=lemoncmd, chdir=1, emitter=lemonemitter, suffix='c')
21258 +env.Append(BUILDERS = {'Lemon': lemonbuilder})
21259 +
21260 +configparser = env.Lemon('configparser.y');
21261 +mod_ssi_exprparser = env.Lemon('mod_ssi_exprparser.y');
21262 +http_resp_parser = env.Lemon('http_resp_parser.y');
21263 +
21264 +env.Alias('http_resp', env.Program('http_resp', 
21265 +    [ 'http_resp_parser.c', 'http_resp.c', 'buffer.c', 'array.c', 'chunk.c',
21266 +      'keyvalue.c', 'data_string.c', 'http_resp_test.c'
21267 +    ] ))
21268 +
21269  ## the modules and how they are built
21270  modules = {
21271         'mod_access' : { 'src' : [ 'mod_access.c' ] },
21272 @@ -42,8 +70,9 @@
21273         'mod_cgi' : { 'src' : [ 'mod_cgi.c' ] },
21274         'mod_fastcgi' : { 'src' : [ 'mod_fastcgi.c' ] },
21275         'mod_scgi' : { 'src' : [ 'mod_scgi.c' ] },
21276 +       'mod_dirlisting' : { 'src' : [ 'mod_dirlisting.c' ], 'lib' : [ env['LIBPCRE'] ] },
21277         'mod_staticfile' : { 'src' : [ 'mod_staticfile.c' ] },
21278 -       'mod_dirlisting' : { 'src' : [ 'mod_dirlisting.c' ], 'lib' : [ env['LIBPCRE'] ] },
21279 +
21280         'mod_indexfile' : { 'src' : [ 'mod_indexfile.c' ] },
21281         'mod_setenv' : { 'src' : [ 'mod_setenv.c' ] },
21282         'mod_rrdtool' : { 'src' : [ 'mod_rrdtool.c' ] },
21283 @@ -63,6 +92,7 @@
21284                 'src' : [ 'mod_auth.c', 'http_auth_digest.c', 'http_auth.c' ], 
21285                 'lib' : [ env['LIBCRYPT'], env['LIBLDAP'], env['LIBLBER'] ] },
21286         'mod_webdav' : { 'src' : [ 'mod_webdav.c' ], 'lib' : [ env['LIBXML2'], env['LIBSQLITE3'] ] },
21287 +       'mod_sql_vhost_core' : { 'src' : [ 'mod_sql_vhost_core.c' ] },
21288         'mod_mysql_vhost' : { 'src' : [ 'mod_mysql_vhost.c' ], 'lib' : [ env['LIBMYSQL'] ] },
21289         'mod_trigger_b4_dl' : { 'src' : [ 'mod_trigger_b4_dl.c' ], 'lib' : [ env['LIBPCRE'] ] },
21290         'mod_cml' : { 
21291 @@ -87,7 +117,7 @@
21292         if modules[module].has_key('lib'):
21293                 staticlib += modules[module]['lib']
21294  
21295 -open('plugin-static.h', 'w+').write(staticinit)
21296 +#file('plugin-static.h', 'wb+').write(staticinit)
21297  
21298  ## turn all src-files into objects
21299  staticobj = []
21300 @@ -148,7 +178,7 @@
21301                 bin_linkflags += [ '-Wl,--export-dynamic' ]
21302  
21303  instbin = env.Program(bin_targets, src, LINKFLAGS = bin_linkflags, LIBS= [ env['LIBS'], common_lib, env['LIBDL'] ])
21304 -env.Depends(instbin, configparser)
21305 +env.Depends(instbin, configparser[1])
21306  
21307  spawn_fcgi = env.Program("spawn-fcgi", "spawn-fcgi.c")
21308  
21309
21310 Property changes on: src/SConscript
21311 ___________________________________________________________________
21312 Name: svn:eol-style
21313    + native
21314
21315 Index: src/data_array.c
21316 ===================================================================
21317 --- src/data_array.c    (.../tags/lighttpd-1.4.11)      (revision 1159)
21318 +++ src/data_array.c    (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
21319 @@ -17,16 +17,16 @@
21320  
21321  static void data_array_free(data_unset *d) {
21322         data_array *ds = (data_array *)d;
21323 -       
21324 +
21325         buffer_free(ds->key);
21326         array_free(ds->value);
21327 -       
21328 +
21329         free(d);
21330  }
21331  
21332  static void data_array_reset(data_unset *d) {
21333         data_array *ds = (data_array *)d;
21334 -       
21335 +
21336         /* reused array elements */
21337         buffer_reset(ds->key);
21338         array_reset(ds->value);
21339 @@ -36,7 +36,7 @@
21340         UNUSED(dst);
21341  
21342         src->free(src);
21343 -       
21344 +
21345         return 0;
21346  }
21347  
21348 @@ -48,18 +48,18 @@
21349  
21350  data_array *data_array_init(void) {
21351         data_array *ds;
21352 -       
21353 +
21354         ds = calloc(1, sizeof(*ds));
21355 -       
21356 +
21357         ds->key = buffer_init();
21358         ds->value = array_init();
21359 -       
21360 +
21361         ds->copy = data_array_copy;
21362         ds->free = data_array_free;
21363         ds->reset = data_array_reset;
21364         ds->insert_dup = data_array_insert_dup;
21365         ds->print = data_array_print;
21366         ds->type = TYPE_ARRAY;
21367 -       
21368 +
21369         return ds;
21370  }
21371
21372 Property changes on: src/data_array.c
21373 ___________________________________________________________________
21374 Name: svn:eol-style
21375    + native
21376
21377 Index: src/mod_cml_funcs.c
21378 ===================================================================
21379 --- src/mod_cml_funcs.c (.../tags/lighttpd-1.4.11)      (revision 1159)
21380 +++ src/mod_cml_funcs.c (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
21381 @@ -4,8 +4,7 @@
21382  #include <stdlib.h>
21383  #include <string.h>
21384  #include <errno.h>
21385 -#include <unistd.h>
21386 -#include <dirent.h>
21387 +
21388  #include <stdio.h>
21389  
21390  #include "buffer.h"
21391 @@ -13,6 +12,7 @@
21392  #include "log.h"
21393  #include "plugin.h"
21394  #include "response.h"
21395 +#include "sys-files.h"
21396  
21397  #include "mod_cml.h"
21398  #include "mod_cml_funcs.h"
21399 @@ -30,7 +30,7 @@
21400  #ifdef USE_OPENSSL
21401  #define IN const
21402  #else
21403 -#define IN 
21404 +#define IN
21405  #endif
21406  #define OUT
21407  
21408 @@ -42,29 +42,29 @@
21409         buffer b;
21410         char hex[33];
21411         int n = lua_gettop(L);
21412 -       
21413 +
21414         b.ptr = hex;
21415         b.used = 0;
21416         b.size = sizeof(hex);
21417 -       
21418 +
21419         if (n != 1) {
21420                 lua_pushstring(L, "md5: expected one argument");
21421                 lua_error(L);
21422         }
21423 -       
21424 +
21425         if (!lua_isstring(L, 1)) {
21426                 lua_pushstring(L, "md5: argument has to be a string");
21427                 lua_error(L);
21428         }
21429 -       
21430 +
21431         MD5_Init(&Md5Ctx);
21432         MD5_Update(&Md5Ctx, (unsigned char *)lua_tostring(L, 1), lua_strlen(L, 1));
21433         MD5_Final(HA1, &Md5Ctx);
21434 -       
21435 +
21436         buffer_copy_string_hex(&b, (char *)HA1, 16);
21437 -       
21438 +
21439         lua_pushstring(L, b.ptr);
21440 -       
21441 +
21442         return 1;
21443  }
21444  
21445 @@ -72,37 +72,37 @@
21446  int f_file_mtime(lua_State *L) {
21447         struct stat st;
21448         int n = lua_gettop(L);
21449 -       
21450 +
21451         if (n != 1) {
21452                 lua_pushstring(L, "file_mtime: expected one argument");
21453                 lua_error(L);
21454         }
21455 -       
21456 +
21457         if (!lua_isstring(L, 1)) {
21458                 lua_pushstring(L, "file_mtime: argument has to be a string");
21459                 lua_error(L);
21460         }
21461 -       
21462 +
21463         if (-1 == stat(lua_tostring(L, 1), &st)) {
21464                 lua_pushnil(L);
21465                 return 1;
21466         }
21467 -       
21468 +
21469         lua_pushnumber(L, st.st_mtime);
21470 -       
21471 +
21472         return 1;
21473  }
21474 -
21475 +#ifndef _WIN32
21476  int f_dir_files_iter(lua_State *L) {
21477         DIR *d;
21478         struct dirent *de;
21479 -       
21480 +
21481         d = lua_touserdata(L, lua_upvalueindex(1));
21482 -       
21483 +
21484         if (NULL == (de = readdir(d))) {
21485                 /* EOF */
21486                 closedir(d);
21487 -               
21488 +
21489                 return 0;
21490         } else {
21491                 lua_pushstring(L, de->d_name);
21492 @@ -113,75 +113,75 @@
21493  int f_dir_files(lua_State *L) {
21494         DIR *d;
21495         int n = lua_gettop(L);
21496 -       
21497 +
21498         if (n != 1) {
21499                 lua_pushstring(L, "dir_files: expected one argument");
21500                 lua_error(L);
21501         }
21502 -       
21503 +
21504         if (!lua_isstring(L, 1)) {
21505                 lua_pushstring(L, "dir_files: argument has to be a string");
21506                 lua_error(L);
21507         }
21508 -       
21509 -       /* check if there is a valid DIR handle on the stack */ 
21510 +
21511 +       /* check if there is a valid DIR handle on the stack */
21512         if (NULL == (d = opendir(lua_tostring(L, 1)))) {
21513                 lua_pushnil(L);
21514                 return 1;
21515         }
21516 -       
21517 +
21518         /* push d into registry */
21519         lua_pushlightuserdata(L, d);
21520         lua_pushcclosure(L, f_dir_files_iter, 1);
21521 -       
21522 +
21523         return 1;
21524  }
21525 -
21526 +#endif
21527  int f_file_isreg(lua_State *L) {
21528         struct stat st;
21529         int n = lua_gettop(L);
21530 -       
21531 +
21532         if (n != 1) {
21533                 lua_pushstring(L, "file_isreg: expected one argument");
21534                 lua_error(L);
21535         }
21536 -       
21537 +
21538         if (!lua_isstring(L, 1)) {
21539                 lua_pushstring(L, "file_isreg: argument has to be a string");
21540                 lua_error(L);
21541         }
21542 -       
21543 +
21544         if (-1 == stat(lua_tostring(L, 1), &st)) {
21545                 lua_pushnil(L);
21546                 return 1;
21547         }
21548 -       
21549 +
21550         lua_pushnumber(L, S_ISREG(st.st_mode));
21551 -       
21552 +
21553         return 1;
21554  }
21555  
21556  int f_file_isdir(lua_State *L) {
21557         struct stat st;
21558         int n = lua_gettop(L);
21559 -       
21560 +
21561         if (n != 1) {
21562                 lua_pushstring(L, "file_isreg: expected one argument");
21563                 lua_error(L);
21564         }
21565 -       
21566 +
21567         if (!lua_isstring(L, 1)) {
21568                 lua_pushstring(L, "file_isreg: argument has to be a string");
21569                 lua_error(L);
21570         }
21571 -       
21572 +
21573         if (-1 == stat(lua_tostring(L, 1), &st)) {
21574                 lua_pushnil(L);
21575                 return 1;
21576         }
21577 -       
21578 +
21579         lua_pushnumber(L, S_ISDIR(st.st_mode));
21580 -       
21581 +
21582         return 1;
21583  }
21584  
21585 @@ -192,33 +192,33 @@
21586         char *r;
21587         int n = lua_gettop(L);
21588         struct memcache *mc;
21589 -       
21590 +
21591         if (!lua_islightuserdata(L, lua_upvalueindex(1))) {
21592                 lua_pushstring(L, "where is my userdata ?");
21593                 lua_error(L);
21594         }
21595 -       
21596 +
21597         mc = lua_touserdata(L, lua_upvalueindex(1));
21598 -       
21599 +
21600         if (n != 1) {
21601                 lua_pushstring(L, "expected one argument");
21602                 lua_error(L);
21603         }
21604 -       
21605 +
21606         if (!lua_isstring(L, 1)) {
21607                 lua_pushstring(L, "argument has to be a string");
21608                 lua_error(L);
21609         }
21610 -       
21611 -       if (NULL == (r = mc_aget(mc, 
21612 +
21613 +       if (NULL == (r = mc_aget(mc,
21614                                  lua_tostring(L, 1), lua_strlen(L, 1)))) {
21615 -                               
21616 +
21617                 lua_pushboolean(L, 0);
21618                 return 1;
21619         }
21620 -       
21621 +
21622         free(r);
21623 -       
21624 +
21625         lua_pushboolean(L, 1);
21626         return 1;
21627  }
21628 @@ -226,74 +226,74 @@
21629  int f_memcache_get_string(lua_State *L) {
21630         char *r;
21631         int n = lua_gettop(L);
21632 -       
21633 +
21634         struct memcache *mc;
21635 -       
21636 +
21637         if (!lua_islightuserdata(L, lua_upvalueindex(1))) {
21638                 lua_pushstring(L, "where is my userdata ?");
21639                 lua_error(L);
21640         }
21641 -       
21642 +
21643         mc = lua_touserdata(L, lua_upvalueindex(1));
21644 -       
21645 -       
21646 +
21647 +
21648         if (n != 1) {
21649                 lua_pushstring(L, "expected one argument");
21650                 lua_error(L);
21651         }
21652 -       
21653 +
21654         if (!lua_isstring(L, 1)) {
21655                 lua_pushstring(L, "argument has to be a string");
21656                 lua_error(L);
21657         }
21658 -       
21659 -       if (NULL == (r = mc_aget(mc, 
21660 +
21661 +       if (NULL == (r = mc_aget(mc,
21662                                  lua_tostring(L, 1), lua_strlen(L, 1)))) {
21663                 lua_pushnil(L);
21664                 return 1;
21665         }
21666 -       
21667 +
21668         lua_pushstring(L, r);
21669 -       
21670 +
21671         free(r);
21672 -       
21673 +
21674         return 1;
21675  }
21676  
21677  int f_memcache_get_long(lua_State *L) {
21678         char *r;
21679         int n = lua_gettop(L);
21680 -       
21681 +
21682         struct memcache *mc;
21683 -       
21684 +
21685         if (!lua_islightuserdata(L, lua_upvalueindex(1))) {
21686                 lua_pushstring(L, "where is my userdata ?");
21687                 lua_error(L);
21688         }
21689 -       
21690 +
21691         mc = lua_touserdata(L, lua_upvalueindex(1));
21692 -       
21693 -       
21694 +
21695 +
21696         if (n != 1) {
21697                 lua_pushstring(L, "expected one argument");
21698                 lua_error(L);
21699         }
21700 -       
21701 +
21702         if (!lua_isstring(L, 1)) {
21703                 lua_pushstring(L, "argument has to be a string");
21704                 lua_error(L);
21705         }
21706 -       
21707 -       if (NULL == (r = mc_aget(mc, 
21708 +
21709 +       if (NULL == (r = mc_aget(mc,
21710                                  lua_tostring(L, 1), lua_strlen(L, 1)))) {
21711                 lua_pushnil(L);
21712                 return 1;
21713         }
21714 -       
21715 +
21716         lua_pushnumber(L, strtol(r, NULL, 10));
21717 -       
21718 +
21719         free(r);
21720 -       
21721 +
21722         return 1;
21723  }
21724  #endif
21725
21726 Property changes on: src/mod_cml_funcs.c
21727 ___________________________________________________________________
21728 Name: svn:eol-style
21729    + native
21730
21731 Index: src/buffer.c
21732 ===================================================================
21733 --- src/buffer.c        (.../tags/lighttpd-1.4.11)      (revision 1159)
21734 +++ src/buffer.c        (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
21735 @@ -12,20 +12,20 @@
21736  
21737  
21738  /**
21739 - * init the buffer 
21740 - * 
21741 + * init the buffer
21742 + *
21743   */
21744  
21745  buffer* buffer_init(void) {
21746         buffer *b;
21747 -       
21748 +
21749         b = malloc(sizeof(*b));
21750         assert(b);
21751 -       
21752 +
21753         b->ptr = NULL;
21754         b->size = 0;
21755         b->used = 0;
21756 -       
21757 +
21758         return b;
21759  }
21760  
21761 @@ -36,8 +36,8 @@
21762  }
21763  
21764  /**
21765 - * free the buffer 
21766 - * 
21767 + * free the buffer
21768 + *
21769   */
21770  
21771  void buffer_free(buffer *b) {
21772 @@ -49,39 +49,39 @@
21773  
21774  void buffer_reset(buffer *b) {
21775         if (!b) return;
21776 -       
21777 +
21778         /* limit don't reuse buffer larger than ... bytes */
21779         if (b->size > BUFFER_MAX_REUSE_SIZE) {
21780                 free(b->ptr);
21781                 b->ptr = NULL;
21782                 b->size = 0;
21783         }
21784 -       
21785 +
21786         b->used = 0;
21787  }
21788  
21789  
21790  /**
21791 - * 
21792 - * allocate (if neccessary) enough space for 'size' bytes and 
21793 + *
21794 + * allocate (if necessary) enough space for 'size' bytes and
21795   * set the 'used' counter to 0
21796 - * 
21797 + *
21798   */
21799  
21800  #define BUFFER_PIECE_SIZE 64
21801  
21802  int buffer_prepare_copy(buffer *b, size_t size) {
21803         if (!b) return -1;
21804 -       
21805 -       if ((0 == b->size) || 
21806 +
21807 +       if ((0 == b->size) ||
21808             (size > b->size)) {
21809                 if (b->size) free(b->ptr);
21810 -               
21811 +
21812                 b->size = size;
21813 -               
21814 -               /* always allocate a multiply of BUFFER_PIECE_SIZE */
21815 +
21816 +               /* always allocate a multiple of BUFFER_PIECE_SIZE */
21817                 b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE);
21818 -               
21819 +
21820                 b->ptr = malloc(b->size);
21821                 assert(b->ptr);
21822         }
21823 @@ -90,30 +90,30 @@
21824  }
21825  
21826  /**
21827 - * 
21828 - * increase the internal buffer (if neccessary) to append another 'size' byte
21829 + *
21830 + * increase the internal buffer (if necessary) to append another 'size' byte
21831   * ->used isn't changed
21832 - * 
21833 + *
21834   */
21835  
21836  int buffer_prepare_append(buffer *b, size_t size) {
21837         if (!b) return -1;
21838 -       
21839 +
21840         if (0 == b->size) {
21841                 b->size = size;
21842 -               
21843 -               /* always allocate a multiply of BUFFER_PIECE_SIZE */
21844 +
21845 +               /* always allocate a multiple of BUFFER_PIECE_SIZE */
21846                 b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE);
21847 -               
21848 +
21849                 b->ptr = malloc(b->size);
21850                 b->used = 0;
21851                 assert(b->ptr);
21852         } else if (b->used + size > b->size) {
21853                 b->size += size;
21854 -               
21855 -               /* always allocate a multiply of BUFFER_PIECE_SIZE */
21856 +
21857 +               /* always allocate a multiple of BUFFER_PIECE_SIZE */
21858                 b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE);
21859 -               
21860 +
21861                 b->ptr = realloc(b->ptr, b->size);
21862                 assert(b->ptr);
21863         }
21864 @@ -122,7 +122,7 @@
21865  
21866  int buffer_copy_string(buffer *b, const char *s) {
21867         size_t s_len;
21868 -       
21869 +
21870         if (!s || !b) return -1;
21871  
21872         s_len = strlen(s) + 1;
21873 @@ -136,26 +136,26 @@
21874  
21875  int buffer_copy_string_len(buffer *b, const char *s, size_t s_len) {
21876         if (!s || !b) return -1;
21877 -#if 0  
21878 -       /* removed optimization as we have to keep the empty string 
21879 +#if 0
21880 +       /* removed optimization as we have to keep the empty string
21881          * in some cases for the config handling
21882 -        * 
21883 +        *
21884          * url.access-deny = ( "" )
21885          */
21886         if (s_len == 0) return 0;
21887 -#endif 
21888 +#endif
21889         buffer_prepare_copy(b, s_len + 1);
21890 -       
21891 +
21892         memcpy(b->ptr, s, s_len);
21893         b->ptr[s_len] = '\0';
21894         b->used = s_len + 1;
21895 -       
21896 +
21897         return 0;
21898  }
21899  
21900  int buffer_copy_string_buffer(buffer *b, const buffer *src) {
21901         if (!src) return -1;
21902 -       
21903 +
21904         if (src->used == 0) {
21905                 b->used = 0;
21906                 return 0;
21907 @@ -201,10 +201,10 @@
21908  
21909  /**
21910   * append a string to the end of the buffer
21911 - * 
21912 - * the resulting buffer is terminated with a '\0' 
21913 - * s is treated as a un-terminated string (a \0 is handled a normal character)
21914 - * 
21915 + *
21916 + * the resulting buffer is terminated with a '\0'
21917 + * s is treated as an un-terminated string (a \0 is handled as a normal character)
21918 + *
21919   * @param b a buffer
21920   * @param s the string
21921   * @param s_len size of the string (without the terminating \0)
21922 @@ -228,7 +228,7 @@
21923  int buffer_append_string_buffer(buffer *b, const buffer *src) {
21924         if (!src) return -1;
21925         if (src->used == 0) return 0;
21926 -       
21927 +
21928         return buffer_append_string_len(b, src->ptr, src->used - 1);
21929  }
21930  
21931 @@ -245,9 +245,9 @@
21932  
21933  int buffer_copy_memory(buffer *b, const char *s, size_t s_len) {
21934         if (!s || !b) return -1;
21935 -       
21936 +
21937         b->used = 0;
21938 -       
21939 +
21940         return buffer_append_memory(b, s, s_len);
21941  }
21942  
21943 @@ -402,46 +402,115 @@
21944  
21945  
21946  /**
21947 - * init the buffer 
21948 - * 
21949 + * init the ptr buffer
21950 + *
21951   */
21952 +buffer_ptr *buffer_ptr_init(buffer_ptr_free_t freer)
21953 +{
21954 +       buffer_ptr *l = calloc(1, sizeof(buffer_ptr));
21955 +       l->free = freer;
21956  
21957 +       return l;
21958 +}
21959 +
21960 +/**
21961 + * free the buffer_array
21962 + *
21963 + */
21964 +void buffer_ptr_free(buffer_ptr *l)
21965 +{
21966 +       if (NULL != l) {
21967 +               buffer_ptr_clear(l);
21968 +               free(l);
21969 +       }
21970 +}
21971 +
21972 +void buffer_ptr_clear(buffer_ptr *l)
21973 +{
21974 +       assert(NULL != l);
21975 +
21976 +       if (l->free && l->used) {
21977 +               size_t i;
21978 +               for (i = 0; i < l->used; i ++) {
21979 +                       l->free(l->ptr[i]);
21980 +               }
21981 +       }
21982 +
21983 +       if (l->ptr) {
21984 +               free(l->ptr);
21985 +               l->ptr = NULL;
21986 +       }
21987 +       l->used = 0;
21988 +       l->size = 0;
21989 +}
21990 +
21991 +void buffer_ptr_append(buffer_ptr* l, void *item)
21992 +{
21993 +       assert(NULL != l);
21994 +       if (l->ptr == NULL) {
21995 +               l->size = 16;
21996 +               l->ptr = (void **)malloc(sizeof(void *) * l->size);
21997 +       }
21998 +       else if (l->used == l->size) {
21999 +               l->size += 16;
22000 +               l->ptr = realloc(l->ptr, sizeof(void *) * l->size);
22001 +       }
22002 +       l->ptr[l->used++] = item;
22003 +}
22004 +
22005 +void *buffer_ptr_pop(buffer_ptr* l)
22006 +{
22007 +       assert(NULL != l && l->used > 0);
22008 +       return l->ptr[--l->used];
22009 +}
22010 +
22011 +void *buffer_ptr_top(buffer_ptr* l)
22012 +{
22013 +       assert(NULL != l && l->used > 0);
22014 +       return l->ptr[l->used-1];
22015 +}
22016 +
22017 +/**
22018 + * init the buffer
22019 + *
22020 + */
22021 +
22022  buffer_array* buffer_array_init(void) {
22023         buffer_array *b;
22024 -       
22025 +
22026         b = malloc(sizeof(*b));
22027 -       
22028 +
22029         assert(b);
22030         b->ptr = NULL;
22031         b->size = 0;
22032         b->used = 0;
22033 -       
22034 +
22035         return b;
22036  }
22037  
22038  void buffer_array_reset(buffer_array *b) {
22039         size_t i;
22040 -       
22041 +
22042         if (!b) return;
22043 -       
22044 +
22045         /* if they are too large, reduce them */
22046         for (i = 0; i < b->used; i++) {
22047                 buffer_reset(b->ptr[i]);
22048         }
22049 -       
22050 +
22051         b->used = 0;
22052  }
22053  
22054  
22055  /**
22056 - * free the buffer_array 
22057 - * 
22058 + * free the buffer_array
22059 + *
22060   */
22061  
22062  void buffer_array_free(buffer_array *b) {
22063         size_t i;
22064         if (!b) return;
22065 -       
22066 +
22067         for (i = 0; i < b->size; i++) {
22068                 if (b->ptr[i]) buffer_free(b->ptr[i]);
22069         }
22070 @@ -451,7 +520,7 @@
22071  
22072  buffer *buffer_array_append_get_buffer(buffer_array *b) {
22073         size_t i;
22074 -       
22075 +
22076         if (b->size == 0) {
22077                 b->size = 16;
22078                 b->ptr = malloc(sizeof(*b->ptr) * b->size);
22079 @@ -467,13 +536,13 @@
22080                         b->ptr[i] = NULL;
22081                 }
22082         }
22083 -       
22084 +
22085         if (b->ptr[b->used] == NULL) {
22086                 b->ptr[b->used] = buffer_init();
22087         }
22088 -       
22089 +
22090         b->ptr[b->used]->used = 0;
22091 -       
22092 +
22093         return b->ptr[b->used++];
22094  }
22095  
22096 @@ -482,23 +551,23 @@
22097         size_t i;
22098         if (len == 0) return NULL;
22099         if (needle == NULL) return NULL;
22100 -       
22101 +
22102         if (b->used < len) return NULL;
22103 -       
22104 +
22105         for(i = 0; i < b->used - len; i++) {
22106                 if (0 == memcmp(b->ptr + i, needle, len)) {
22107                         return b->ptr + i;
22108                 }
22109         }
22110 -       
22111 +
22112         return NULL;
22113  }
22114  
22115  buffer *buffer_init_string(const char *str) {
22116         buffer *b = buffer_init();
22117 -       
22118 +
22119         buffer_copy_string(b, str);
22120 -       
22121 +
22122         return b;
22123  }
22124  
22125 @@ -507,8 +576,8 @@
22126  }
22127  
22128  /**
22129 - * check if two buffer contain the same data
22130 - * 
22131 + * check if two buffers contain the same data
22132 + *
22133   * HISTORY: this function was pretty much optimized, but didn't handled
22134   * alignment properly.
22135   */
22136 @@ -522,100 +591,100 @@
22137  
22138  int buffer_is_equal_string(buffer *a, const char *s, size_t b_len) {
22139         buffer b;
22140 -       
22141 +
22142         b.ptr = (char *)s;
22143         b.used = b_len + 1;
22144 -       
22145 +
22146         return buffer_is_equal(a, &b);
22147  }
22148  
22149  /* simple-assumption:
22150 - * 
22151 - * most parts are equal and doing a case conversion needs time
22152 - * 
22153 + *
22154 + * most parts are equal and doing a case conversion takes time
22155 + *
22156   */
22157  int buffer_caseless_compare(const char *a, size_t a_len, const char *b, size_t b_len) {
22158         size_t ndx = 0, max_ndx;
22159         size_t *al, *bl;
22160         size_t mask = sizeof(*al) - 1;
22161 -       
22162 +
22163         al = (size_t *)a;
22164         bl = (size_t *)b;
22165 -       
22166 -       /* is the alignment correct ? */
22167 +
22168 +       /* is the alignment correct? */
22169         if ( ((size_t)al & mask) == 0 &&
22170              ((size_t)bl & mask) == 0 ) {
22171 -               
22172 +
22173                 max_ndx = ((a_len < b_len) ? a_len : b_len) & ~mask;
22174 -               
22175 +
22176                 for (; ndx < max_ndx; ndx += sizeof(*al)) {
22177                         if (*al != *bl) break;
22178                         al++; bl++;
22179 -                       
22180 +
22181                 }
22182 -               
22183 +
22184         }
22185 -       
22186 +
22187         a = (char *)al;
22188         b = (char *)bl;
22189 -       
22190 +
22191         max_ndx = ((a_len < b_len) ? a_len : b_len);
22192 -       
22193 +
22194         for (; ndx < max_ndx; ndx++) {
22195                 char a1 = *a++, b1 = *b++;
22196 -               
22197 +
22198                 if (a1 != b1) {
22199                         if ((a1 >= 'A' && a1 <= 'Z') && (b1 >= 'a' && b1 <= 'z'))
22200                                 a1 |= 32;
22201                         else if ((a1 >= 'a' && a1 <= 'z') && (b1 >= 'A' && b1 <= 'Z'))
22202                                 b1 |= 32;
22203                         if ((a1 - b1) != 0) return (a1 - b1);
22204 -                       
22205 +
22206                 }
22207         }
22208 -       
22209 +
22210         return 0;
22211  }
22212  
22213  
22214  /**
22215   * check if the rightmost bytes of the string are equal.
22216 - * 
22217 - * 
22218 + *
22219 + *
22220   */
22221  
22222  int buffer_is_equal_right_len(buffer *b1, buffer *b2, size_t len) {
22223         /* no, len -> equal */
22224         if (len == 0) return 1;
22225 -       
22226 +
22227         /* len > 0, but empty buffers -> not equal */
22228         if (b1->used == 0 || b2->used == 0) return 0;
22229 -       
22230 +
22231         /* buffers too small -> not equal */
22232 -       if (b1->used - 1 < len || b1->used - 1 < len) return 0;
22233 -       
22234 -       if (0 == strncmp(b1->ptr + b1->used - 1 - len, 
22235 +       if (b1->used - 1 < len || b2->used - 1 < len) return 0;
22236 +
22237 +       if (0 == strncmp(b1->ptr + b1->used - 1 - len,
22238                          b2->ptr + b2->used - 1 - len, len)) {
22239                 return 1;
22240         }
22241 -       
22242 +
22243         return 0;
22244  }
22245  
22246  int buffer_copy_string_hex(buffer *b, const char *in, size_t in_len) {
22247         size_t i;
22248 -       
22249 +
22250         /* BO protection */
22251         if (in_len * 2 < in_len) return -1;
22252 -       
22253 +
22254         buffer_prepare_copy(b, in_len * 2 + 1);
22255 -       
22256 +
22257         for (i = 0; i < in_len; i++) {
22258                 b->ptr[b->used++] = hex_chars[(in[i] >> 4) & 0x0F];
22259                 b->ptr[b->used++] = hex_chars[in[i] & 0x0F];
22260         }
22261         b->ptr[b->used++] = '\0';
22262 -       
22263 +
22264         return 0;
22265  }
22266  
22267 @@ -624,7 +693,7 @@
22268         0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
22269         */
22270         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  00 -  0F control chars */
22271 -       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  10 -  1F */ 
22272 +       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  10 -  1F */
22273         1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1,  /*  20 -  2F space " # $ % & ' + , / */
22274         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,  /*  30 -  3F : ; = ? @ < > */
22275         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /*  40 -  4F */
22276 @@ -646,7 +715,7 @@
22277         0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
22278         */
22279         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  00 -  0F control chars */
22280 -       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  10 -  1F */ 
22281 +       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  10 -  1F */
22282         1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0,  /*  20 -  2F space " # $ % & ' + , / */
22283         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,  /*  30 -  3F : ; = ? @ < > */
22284         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /*  40 -  4F */
22285 @@ -668,7 +737,7 @@
22286         0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
22287         */
22288         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  00 -  0F control chars */
22289 -       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  10 -  1F */ 
22290 +       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  10 -  1F */
22291         0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /*  20 -  2F & */
22292         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,  /*  30 -  3F < > */
22293         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /*  40 -  4F */
22294 @@ -690,7 +759,7 @@
22295         0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
22296         */
22297         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  00 -  0F control chars */
22298 -       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  10 -  1F */ 
22299 +       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  10 -  1F */
22300         0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /*  20 -  2F & */
22301         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,  /*  30 -  3F < > */
22302         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /*  40 -  4F */
22303 @@ -712,12 +781,12 @@
22304         0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
22305         */
22306         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  00 -  0F control chars */
22307 -       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  10 -  1F */ 
22308 -       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  20 -  2F */ 
22309 -       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  30 -  3F */ 
22310 -       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  40 -  4F */ 
22311 -       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  50 -  5F */ 
22312 -       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  60 -  6F */ 
22313 +       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  10 -  1F */
22314 +       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  20 -  2F */
22315 +       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  30 -  3F */
22316 +       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  40 -  4F */
22317 +       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  50 -  5F */
22318 +       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  60 -  6F */
22319         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  70 -  7F */
22320         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  80 -  8F */
22321         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /*  90 -  9F */
22322 @@ -734,13 +803,13 @@
22323         unsigned char *ds, *d;
22324         size_t d_len, ndx;
22325         const char *map = NULL;
22326 -       
22327 +
22328         if (!s || !b) return -1;
22329 -       
22330 +
22331         if (b->ptr[b->used - 1] != '\0') {
22332                 SEGFAULT();
22333         }
22334 -       
22335 +
22336         if (s_len == 0) return 0;
22337  
22338         switch(encoding) {
22339 @@ -760,12 +829,12 @@
22340                 map = encoded_chars_hex;
22341                 break;
22342         case ENCODING_UNSET:
22343 -               break;
22344 +               return buffer_append_string_len(b, s, s_len);
22345         }
22346  
22347         assert(map != NULL);
22348 -       
22349 -       /* count to-be-encoded-characters */
22350 +
22351 +       /* count to-be-encoded characters */
22352         for (ds = (unsigned char *)s, d_len = 0, ndx = 0; ndx < s_len; ds++, ndx++) {
22353                 if (map[*ds]) {
22354                         switch(encoding) {
22355 @@ -787,9 +856,9 @@
22356                         d_len ++;
22357                 }
22358         }
22359 -       
22360 +
22361         buffer_prepare_append(b, d_len);
22362 -       
22363 +
22364         for (ds = (unsigned char *)s, d = (unsigned char *)b->ptr + b->used - 1, d_len = 0, ndx = 0; ndx < s_len; ds++, ndx++) {
22365                 if (map[*ds]) {
22366                         switch(encoding) {
22367 @@ -820,16 +889,16 @@
22368                 }
22369         }
22370  
22371 -       /* terminate buffer and calculate new length */ 
22372 +       /* terminate buffer and calculate new length */
22373         b->ptr[b->used + d_len - 1] = '\0';
22374 -       
22375 +
22376         b->used += d_len;
22377  
22378         return 0;
22379  }
22380  
22381  
22382 -/* decodes url-special-chars inplace.
22383 +/* decodes url-special chars in-place.
22384   * replaces non-printable characters with '_'
22385   */
22386  
22387 @@ -854,10 +923,10 @@
22388                                 low = hex2int(*(src + 2));
22389                                 if (low != 0xFF) {
22390                                         high = (high << 4) | low;
22391 -                                       
22392 -                                       /* map control-characters out */        
22393 +
22394 +                                       /* map out control characters */
22395                                         if (high < 32 || high == 127) high = '_';
22396 -                                       
22397 +
22398                                         *dst = high;
22399                                         src += 2;
22400                                 }
22401 @@ -891,7 +960,7 @@
22402   * /abc/./xyz       gets  /abc/xyz
22403   * /abc//xyz        gets  /abc/xyz
22404   *
22405 - * NOTE: src and dest can point to the same buffer, in which case,
22406 + * NOTE: src and dest can point to the same buffer, in which case
22407   *       the operation is performed in-place.
22408   */
22409  
22410 @@ -979,7 +1048,7 @@
22411  
22412  int light_isxdigit(int c) {
22413         if (light_isdigit(c)) return 1;
22414 -       
22415 +
22416         c |= 32;
22417         return (c >= 'a' && c <= 'f');
22418  }
22419 @@ -993,31 +1062,56 @@
22420         return light_isdigit(c) || light_isalpha(c);
22421  }
22422  
22423 +#undef BUFFER_CTYPE_FUNC
22424 +#define BUFFER_CTYPE_FUNC(type) \
22425 +       int buffer_is##type(buffer *b) { \
22426 +               size_t i, len; \
22427 +               if (b->used < 2) return 0; \
22428 +               /* strlen */ \
22429 +               len = b->used - 1; \
22430 +               /* c-string only */ \
22431 +               if (b->ptr[len] != '\0') { \
22432 +                       return 0; \
22433 +               } \
22434 +               /* check on the whole string */ \
22435 +               for (i = 0; i < len; i ++) { \
22436 +                       if (!light_is##type(b->ptr[i])) { \
22437 +                               return 0; \
22438 +                       } \
22439 +               } \
22440 +               return 1; \
22441 +       }
22442 +
22443 +BUFFER_CTYPE_FUNC(digit)
22444 +BUFFER_CTYPE_FUNC(xdigit)
22445 +BUFFER_CTYPE_FUNC(alpha)
22446 +BUFFER_CTYPE_FUNC(alnum)
22447 +
22448  int buffer_to_lower(buffer *b) {
22449         char *c;
22450 -       
22451 +
22452         if (b->used == 0) return 0;
22453 -       
22454 +
22455         for (c = b->ptr; *c; c++) {
22456                 if (*c >= 'A' && *c <= 'Z') {
22457                         *c |= 32;
22458                 }
22459         }
22460 -       
22461 +
22462         return 0;
22463  }
22464  
22465  
22466  int buffer_to_upper(buffer *b) {
22467         char *c;
22468 -       
22469 +
22470         if (b->used == 0) return 0;
22471 -       
22472 +
22473         for (c = b->ptr; *c; c++) {
22474                 if (*c >= 'a' && *c <= 'z') {
22475                         *c &= ~32;
22476                 }
22477         }
22478 -       
22479 +
22480         return 0;
22481  }
22482
22483 Property changes on: src/buffer.c
22484 ___________________________________________________________________
22485 Name: svn:eol-style
22486    + native
22487
22488 Index: src/mod_simple_vhost.c
22489 ===================================================================
22490 --- src/mod_simple_vhost.c      (.../tags/lighttpd-1.4.11)      (revision 1159)
22491 +++ src/mod_simple_vhost.c      (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
22492 @@ -10,6 +10,8 @@
22493  
22494  #include "plugin.h"
22495  
22496 +#include "sys-files.h"
22497 +
22498  #ifdef HAVE_CONFIG_H
22499  #include "config.h"
22500  #endif
22501 @@ -18,7 +20,7 @@
22502         buffer *server_root;
22503         buffer *default_host;
22504         buffer *document_root;
22505 -       
22506 +
22507         buffer *docroot_cache_key;
22508         buffer *docroot_cache_value;
22509         buffer *docroot_cache_servername;
22510 @@ -28,138 +30,138 @@
22511  
22512  typedef struct {
22513         PLUGIN_DATA;
22514 -       
22515 +
22516         buffer *doc_root;
22517 -       
22518 +
22519         plugin_config **config_storage;
22520 -       plugin_config conf; 
22521 +       plugin_config conf;
22522  } plugin_data;
22523  
22524  INIT_FUNC(mod_simple_vhost_init) {
22525         plugin_data *p;
22526 -       
22527 +
22528         p = calloc(1, sizeof(*p));
22529 -       
22530 +
22531         p->doc_root = buffer_init();
22532 -       
22533 +
22534         return p;
22535  }
22536  
22537  FREE_FUNC(mod_simple_vhost_free) {
22538         plugin_data *p = p_d;
22539 -       
22540 +
22541         UNUSED(srv);
22542  
22543         if (!p) return HANDLER_GO_ON;
22544 -       
22545 +
22546         if (p->config_storage) {
22547                 size_t i;
22548                 for (i = 0; i < srv->config_context->used; i++) {
22549                         plugin_config *s = p->config_storage[i];
22550 -                       
22551 +
22552                         buffer_free(s->document_root);
22553                         buffer_free(s->default_host);
22554                         buffer_free(s->server_root);
22555 -                       
22556 +
22557                         buffer_free(s->docroot_cache_key);
22558                         buffer_free(s->docroot_cache_value);
22559                         buffer_free(s->docroot_cache_servername);
22560 -                       
22561 +
22562                         free(s);
22563                 }
22564 -       
22565 +
22566                 free(p->config_storage);
22567         }
22568 -       
22569 +
22570         buffer_free(p->doc_root);
22571 -       
22572 +
22573         free(p);
22574 -       
22575 +
22576         return HANDLER_GO_ON;
22577  }
22578  
22579  SETDEFAULTS_FUNC(mod_simple_vhost_set_defaults) {
22580         plugin_data *p = p_d;
22581         size_t i;
22582 -       
22583 -       config_values_t cv[] = { 
22584 +
22585 +       config_values_t cv[] = {
22586                 { "simple-vhost.server-root",       NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
22587                 { "simple-vhost.default-host",      NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
22588                 { "simple-vhost.document-root",     NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
22589                 { "simple-vhost.debug",             NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },
22590                 { NULL,                             NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
22591         };
22592 -       
22593 +
22594         if (!p) return HANDLER_ERROR;
22595 -       
22596 +
22597         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
22598 -       
22599 +
22600         for (i = 0; i < srv->config_context->used; i++) {
22601                 plugin_config *s;
22602 -               
22603 +
22604                 s = calloc(1, sizeof(plugin_config));
22605 -               
22606 +
22607                 s->server_root = buffer_init();
22608                 s->default_host = buffer_init();
22609                 s->document_root = buffer_init();
22610 -               
22611 +
22612                 s->docroot_cache_key = buffer_init();
22613                 s->docroot_cache_value = buffer_init();
22614                 s->docroot_cache_servername = buffer_init();
22615  
22616                 s->debug = 0;
22617 -               
22618 +
22619                 cv[0].destination = s->server_root;
22620                 cv[1].destination = s->default_host;
22621                 cv[2].destination = s->document_root;
22622                 cv[3].destination = &(s->debug);
22623 -               
22624 -               
22625 +
22626 +
22627                 p->config_storage[i] = s;
22628 -               
22629 +
22630                 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
22631                         return HANDLER_ERROR;
22632                 }
22633         }
22634 -       
22635 +
22636         return HANDLER_GO_ON;
22637  }
22638  
22639  static int build_doc_root(server *srv, connection *con, plugin_data *p, buffer *out, buffer *host) {
22640         stat_cache_entry *sce = NULL;
22641 -       
22642 +
22643         buffer_prepare_copy(out, 128);
22644  
22645         if (p->conf.server_root->used) {
22646                 buffer_copy_string_buffer(out, p->conf.server_root);
22647 -               
22648 +
22649                 if (host->used) {
22650                         /* a hostname has to start with a alpha-numerical character
22651                          * and must not contain a slash "/"
22652                          */
22653                         char *dp;
22654 -                       
22655 -                       BUFFER_APPEND_SLASH(out);
22656 -                       
22657 +
22658 +                       PATHNAME_APPEND_SLASH(out);
22659 +
22660                         if (NULL == (dp = strchr(host->ptr, ':'))) {
22661                                 buffer_append_string_buffer(out, host);
22662                         } else {
22663                                 buffer_append_string_len(out, host->ptr, dp - host->ptr);
22664                         }
22665                 }
22666 -               BUFFER_APPEND_SLASH(out);
22667 -               
22668 +               PATHNAME_APPEND_SLASH(out);
22669 +
22670                 if (p->conf.document_root->used > 2 && p->conf.document_root->ptr[0] == '/') {
22671                         buffer_append_string_len(out, p->conf.document_root->ptr + 1, p->conf.document_root->used - 2);
22672                 } else {
22673                         buffer_append_string_buffer(out, p->conf.document_root);
22674 -                       BUFFER_APPEND_SLASH(out);
22675 +                       PATHNAME_APPEND_SLASH(out);
22676                 }
22677         } else {
22678                 buffer_copy_string_buffer(out, con->conf.document_root);
22679 -               BUFFER_APPEND_SLASH(out);
22680 +               PATHNAME_APPEND_SLASH(out);
22681         }
22682 -       
22683 +
22684         if (HANDLER_ERROR == stat_cache_get_entry(srv, con, out, &sce)) {
22685                 if (p->conf.debug) {
22686                         log_error_write(srv, __FILE__, __LINE__, "sb",
22687 @@ -169,57 +171,53 @@
22688         } else if (!S_ISDIR(sce->st.st_mode)) {
22689                 return -1;
22690         }
22691 -       
22692 +
22693         return 0;
22694  }
22695  
22696 -
22697 -#define PATCH(x) \
22698 -       p->conf.x = s->x;
22699  static int mod_simple_vhost_patch_connection(server *srv, connection *con, plugin_data *p) {
22700         size_t i, j;
22701         plugin_config *s = p->config_storage[0];
22702 -       
22703 -       PATCH(server_root);
22704 -       PATCH(default_host);
22705 -       PATCH(document_root);
22706 -       
22707 -       PATCH(docroot_cache_key);
22708 -       PATCH(docroot_cache_value);
22709 -       PATCH(docroot_cache_servername);
22710  
22711 -       PATCH(debug);
22712 -       
22713 +       PATCH_OPTION(server_root);
22714 +       PATCH_OPTION(default_host);
22715 +       PATCH_OPTION(document_root);
22716 +
22717 +       PATCH_OPTION(docroot_cache_key);
22718 +       PATCH_OPTION(docroot_cache_value);
22719 +       PATCH_OPTION(docroot_cache_servername);
22720 +
22721 +       PATCH_OPTION(debug);
22722 +
22723         /* skip the first, the global context */
22724         for (i = 1; i < srv->config_context->used; i++) {
22725                 data_config *dc = (data_config *)srv->config_context->data[i];
22726                 s = p->config_storage[i];
22727 -               
22728 +
22729                 /* condition didn't match */
22730                 if (!config_check_cond(srv, con, dc)) continue;
22731 -               
22732 +
22733                 /* merge config */
22734                 for (j = 0; j < dc->value->used; j++) {
22735                         data_unset *du = dc->value->data[j];
22736 -                       
22737 +
22738                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("simple-vhost.server-root"))) {
22739 -                               PATCH(server_root);
22740 -                               PATCH(docroot_cache_key);
22741 -                               PATCH(docroot_cache_value);
22742 -                               PATCH(docroot_cache_servername);
22743 +                               PATCH_OPTION(server_root);
22744 +                               PATCH_OPTION(docroot_cache_key);
22745 +                               PATCH_OPTION(docroot_cache_value);
22746 +                               PATCH_OPTION(docroot_cache_servername);
22747                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("simple-vhost.default-host"))) {
22748 -                               PATCH(default_host);
22749 +                               PATCH_OPTION(default_host);
22750                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("simple-vhost.document-root"))) {
22751 -                               PATCH(document_root);
22752 +                               PATCH_OPTION(document_root);
22753                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("simple-vhost.debug"))) {
22754 -                               PATCH(debug);
22755 +                               PATCH_OPTION(debug);
22756                         }
22757                 }
22758         }
22759 -       
22760 +
22761         return 0;
22762  }
22763 -#undef PATCH
22764  
22765  static handler_t mod_simple_vhost_docroot(server *srv, connection *con, void *p_data) {
22766         plugin_data *p = p_data;
22767 @@ -227,12 +225,12 @@
22768         /*
22769          * cache the last successfull translation from hostname (authority) to docroot
22770          * - this saves us a stat() call
22771 -        * 
22772 +        *
22773          */
22774 -       
22775 +
22776         mod_simple_vhost_patch_connection(srv, con, p);
22777 -       
22778 -       if (p->conf.docroot_cache_key->used && 
22779 +
22780 +       if (p->conf.docroot_cache_key->used &&
22781             con->uri.authority->used &&
22782             buffer_is_equal(p->conf.docroot_cache_key, con->uri.authority)) {
22783                 /* cache hit */
22784 @@ -243,8 +241,8 @@
22785                 if ((con->uri.authority->used == 0) ||
22786                     build_doc_root(srv, con, p, p->doc_root, con->uri.authority)) {
22787                         /* not found, fallback the default-host */
22788 -                       if (build_doc_root(srv, con, p, 
22789 -                                          p->doc_root, 
22790 +                       if (build_doc_root(srv, con, p,
22791 +                                          p->doc_root,
22792                                            p->conf.default_host)) {
22793                                 return HANDLER_GO_ON;
22794                         } else {
22795 @@ -253,15 +251,15 @@
22796                 } else {
22797                         buffer_copy_string_buffer(con->server_name, con->uri.authority);
22798                 }
22799 -               
22800 +
22801                 /* copy to cache */
22802                 buffer_copy_string_buffer(p->conf.docroot_cache_key,        con->uri.authority);
22803                 buffer_copy_string_buffer(p->conf.docroot_cache_value,      p->doc_root);
22804                 buffer_copy_string_buffer(p->conf.docroot_cache_servername, con->server_name);
22805 -               
22806 +
22807                 buffer_copy_string_buffer(con->physical.doc_root, p->doc_root);
22808         }
22809 -       
22810 +
22811         return HANDLER_GO_ON;
22812  }
22813  
22814 @@ -269,13 +267,13 @@
22815  int mod_simple_vhost_plugin_init(plugin *p) {
22816         p->version     = LIGHTTPD_VERSION_ID;
22817         p->name        = buffer_init_string("simple_vhost");
22818 -       
22819 +
22820         p->init        = mod_simple_vhost_init;
22821         p->set_defaults = mod_simple_vhost_set_defaults;
22822         p->handle_docroot  = mod_simple_vhost_docroot;
22823         p->cleanup     = mod_simple_vhost_free;
22824 -       
22825 +
22826         p->data        = NULL;
22827 -       
22828 +
22829         return 0;
22830  }
22831
22832 Property changes on: src/mod_simple_vhost.c
22833 ___________________________________________________________________
22834 Name: svn:eol-style
22835    + native
22836
22837 Index: src/mod_userdir.c
22838 ===================================================================
22839 --- src/mod_userdir.c   (.../tags/lighttpd-1.4.11)      (revision 1159)
22840 +++ src/mod_userdir.c   (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
22841 @@ -10,6 +10,7 @@
22842  #include "response.h"
22843  
22844  #include "plugin.h"
22845 +#include "sys-files.h"
22846  
22847  #ifdef HAVE_PWD_H
22848  #include <pwd.h>
22849 @@ -25,54 +26,54 @@
22850  
22851  typedef struct {
22852         PLUGIN_DATA;
22853 -       
22854 +
22855         buffer *username;
22856         buffer *temp_path;
22857 -       
22858 +
22859         plugin_config **config_storage;
22860 -       
22861 -       plugin_config conf; 
22862 +
22863 +       plugin_config conf;
22864  } plugin_data;
22865  
22866  /* init the plugin data */
22867  INIT_FUNC(mod_userdir_init) {
22868         plugin_data *p;
22869 -       
22870 +
22871         p = calloc(1, sizeof(*p));
22872 -       
22873 +
22874         p->username = buffer_init();
22875         p->temp_path = buffer_init();
22876 -       
22877 +
22878         return p;
22879  }
22880  
22881  /* detroy the plugin data */
22882  FREE_FUNC(mod_userdir_free) {
22883         plugin_data *p = p_d;
22884 -       
22885 +
22886         if (!p) return HANDLER_GO_ON;
22887 -       
22888 +
22889         if (p->config_storage) {
22890                 size_t i;
22891 -               
22892 +
22893                 for (i = 0; i < srv->config_context->used; i++) {
22894                         plugin_config *s = p->config_storage[i];
22895 -                       
22896 +
22897                         array_free(s->include_user);
22898                         array_free(s->exclude_user);
22899                         buffer_free(s->path);
22900                         buffer_free(s->basepath);
22901 -                       
22902 +
22903                         free(s);
22904                 }
22905                 free(p->config_storage);
22906         }
22907 -       
22908 +
22909         buffer_free(p->username);
22910         buffer_free(p->temp_path);
22911 -       
22912 +
22913         free(p);
22914 -       
22915 +
22916         return HANDLER_GO_ON;
22917  }
22918  
22919 @@ -81,81 +82,78 @@
22920  SETDEFAULTS_FUNC(mod_userdir_set_defaults) {
22921         plugin_data *p = p_d;
22922         size_t i;
22923 -       
22924 -       config_values_t cv[] = { 
22925 +
22926 +       config_values_t cv[] = {
22927                 { "userdir.path",               NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
22928                 { "userdir.exclude-user",       NULL, T_CONFIG_ARRAY,  T_CONFIG_SCOPE_CONNECTION },       /* 1 */
22929                 { "userdir.include-user",       NULL, T_CONFIG_ARRAY,  T_CONFIG_SCOPE_CONNECTION },       /* 2 */
22930                 { "userdir.basepath",           NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 3 */
22931                 { NULL,                         NULL, T_CONFIG_UNSET,  T_CONFIG_SCOPE_UNSET }
22932         };
22933 -       
22934 +
22935         if (!p) return HANDLER_ERROR;
22936 -       
22937 +
22938         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
22939 -       
22940 +
22941         for (i = 0; i < srv->config_context->used; i++) {
22942                 plugin_config *s;
22943 -               
22944 +
22945                 s = calloc(1, sizeof(plugin_config));
22946                 s->exclude_user = array_init();
22947                 s->include_user = array_init();
22948                 s->path = buffer_init();
22949                 s->basepath = buffer_init();
22950 -       
22951 +
22952                 cv[0].destination = s->path;
22953                 cv[1].destination = s->exclude_user;
22954                 cv[2].destination = s->include_user;
22955                 cv[3].destination = s->basepath;
22956 -               
22957 +
22958                 p->config_storage[i] = s;
22959 -       
22960 +
22961                 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
22962                         return HANDLER_ERROR;
22963                 }
22964         }
22965 -       
22966 +
22967         return HANDLER_GO_ON;
22968  }
22969  
22970 -#define PATCH(x) \
22971 -       p->conf.x = s->x;
22972  static int mod_userdir_patch_connection(server *srv, connection *con, plugin_data *p) {
22973         size_t i, j;
22974         plugin_config *s = p->config_storage[0];
22975 -       
22976 -       PATCH(path);
22977 -       PATCH(exclude_user);
22978 -       PATCH(include_user);
22979 -       PATCH(basepath);
22980 -       
22981 +
22982 +       PATCH_OPTION(path);
22983 +       PATCH_OPTION(exclude_user);
22984 +       PATCH_OPTION(include_user);
22985 +       PATCH_OPTION(basepath);
22986 +
22987         /* skip the first, the global context */
22988         for (i = 1; i < srv->config_context->used; i++) {
22989                 data_config *dc = (data_config *)srv->config_context->data[i];
22990                 s = p->config_storage[i];
22991 -               
22992 +
22993                 /* condition didn't match */
22994                 if (!config_check_cond(srv, con, dc)) continue;
22995 -               
22996 +
22997                 /* merge config */
22998                 for (j = 0; j < dc->value->used; j++) {
22999                         data_unset *du = dc->value->data[j];
23000 -                       
23001 +
23002                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("userdir.path"))) {
23003 -                               PATCH(path);
23004 +                               PATCH_OPTION(path);
23005                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("userdir.exclude-user"))) {
23006 -                               PATCH(exclude_user);
23007 +                               PATCH_OPTION(exclude_user);
23008                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("userdir.include-user"))) {
23009 -                               PATCH(include_user);
23010 +                               PATCH_OPTION(include_user);
23011                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("userdir.basepath"))) {
23012 -                               PATCH(basepath);
23013 +                               PATCH_OPTION(basepath);
23014                         }
23015                 }
23016         }
23017 -       
23018 +
23019         return 0;
23020  }
23021 -#undef PATCH
23022  
23023  URIHANDLER_FUNC(mod_userdir_docroot_handler) {
23024         plugin_data *p = p_d;
23025 @@ -169,18 +167,18 @@
23026         if (con->uri.path->used == 0) return HANDLER_GO_ON;
23027  
23028         mod_userdir_patch_connection(srv, con, p);
23029 -       
23030 +
23031         uri_len = con->uri.path->used - 1;
23032 -       
23033 +
23034         /* /~user/foo.html -> /home/user/public_html/foo.html */
23035 -       
23036 +
23037         if (con->uri.path->ptr[0] != '/' ||
23038             con->uri.path->ptr[1] != '~') return HANDLER_GO_ON;
23039 -       
23040 +
23041         if (NULL == (rel_url = strchr(con->uri.path->ptr + 2, '/'))) {
23042                 /* / is missing -> redirect to .../ as we are a user - DIRECTORY ! :) */
23043                 http_response_redirect_to_directory(srv, con);
23044 -               
23045 +
23046                 return HANDLER_FINISHED;
23047         }
23048  
23049 @@ -188,10 +186,10 @@
23050         if (0 == rel_url - (con->uri.path->ptr + 2)) {
23051                 return HANDLER_GO_ON;
23052         }
23053 -       
23054 +
23055         buffer_copy_string_len(p->username, con->uri.path->ptr + 2, rel_url - (con->uri.path->ptr + 2));
23056 -       
23057 -       if (buffer_is_empty(p->conf.basepath) 
23058 +
23059 +       if (buffer_is_empty(p->conf.basepath)
23060  #ifdef HAVE_PWD_H
23061             && NULL == (pwd = getpwnam(p->username->ptr))
23062  #endif
23063 @@ -200,31 +198,31 @@
23064                 return HANDLER_GO_ON;
23065         }
23066  
23067 -       
23068 +
23069         for (k = 0; k < p->conf.exclude_user->used; k++) {
23070                 data_string *ds = (data_string *)p->conf.exclude_user->data[k];
23071 -               
23072 +
23073                 if (buffer_is_equal(ds->value, p->username)) {
23074                         /* user in exclude list */
23075                         return HANDLER_GO_ON;
23076                 }
23077         }
23078 -       
23079 +
23080         if (p->conf.include_user->used) {
23081                 int found_user = 0;
23082                 for (k = 0; k < p->conf.include_user->used; k++) {
23083                         data_string *ds = (data_string *)p->conf.include_user->data[k];
23084 -                       
23085 +
23086                         if (buffer_is_equal(ds->value, p->username)) {
23087                                 /* user in include list */
23088                                 found_user = 1;
23089                                 break;
23090                         }
23091                 }
23092 -               
23093 +
23094                 if (!found_user) return HANDLER_GO_ON;
23095         }
23096 -       
23097 +
23098         /* we build the physical path */
23099  
23100         if (buffer_is_empty(p->conf.basepath)) {
23101 @@ -252,23 +250,23 @@
23102                 }
23103  
23104                 buffer_copy_string_buffer(p->temp_path, p->conf.basepath);
23105 -               BUFFER_APPEND_SLASH(p->temp_path);
23106 +               PATHNAME_APPEND_SLASH(p->temp_path);
23107                 buffer_append_string_buffer(p->temp_path, p->username);
23108         }
23109 -       BUFFER_APPEND_SLASH(p->temp_path);
23110 -       buffer_append_string_buffer(p->temp_path, p->conf.path); 
23111 +       PATHNAME_APPEND_SLASH(p->temp_path);
23112 +       buffer_append_string_buffer(p->temp_path, p->conf.path);
23113  
23114         if (buffer_is_empty(p->conf.basepath)) {
23115                 struct stat st;
23116                 int ret;
23117 -               
23118 +
23119                 ret = stat(p->temp_path->ptr, &st);
23120                 if (ret < 0 || S_ISDIR(st.st_mode) != 1) {
23121                         return HANDLER_GO_ON;
23122 -               } 
23123 +               }
23124         }
23125  
23126 -       BUFFER_APPEND_SLASH(p->temp_path);
23127 +       PATHNAME_APPEND_SLASH(p->temp_path);
23128         buffer_append_string(p->temp_path, rel_url + 1); /* skip the / */
23129         buffer_copy_string_buffer(con->physical.path, p->temp_path);
23130  
23131 @@ -282,13 +280,13 @@
23132  int mod_userdir_plugin_init(plugin *p) {
23133         p->version     = LIGHTTPD_VERSION_ID;
23134         p->name        = buffer_init_string("userdir");
23135 -       
23136 +
23137         p->init           = mod_userdir_init;
23138         p->handle_physical = mod_userdir_docroot_handler;
23139         p->set_defaults   = mod_userdir_set_defaults;
23140         p->cleanup        = mod_userdir_free;
23141 -       
23142 +
23143         p->data        = NULL;
23144 -       
23145 +
23146         return 0;
23147  }
23148
23149 Property changes on: src/mod_userdir.c
23150 ___________________________________________________________________
23151 Name: svn:eol-style
23152    + native
23153
23154
23155 Property changes on: src/mod_cml_funcs.h
23156 ___________________________________________________________________
23157 Name: svn:eol-style
23158    + native
23159
23160 Index: src/buffer.h
23161 ===================================================================
23162 --- src/buffer.h        (.../tags/lighttpd-1.4.11)      (revision 1159)
23163 +++ src/buffer.h        (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
23164 @@ -12,27 +12,44 @@
23165  
23166  typedef struct {
23167         char *ptr;
23168 -       
23169 +
23170         size_t used;
23171         size_t size;
23172  } buffer;
23173  
23174 +
23175 +typedef void (*buffer_ptr_free_t)(void *p);
23176 +
23177  typedef struct {
23178 +       void **ptr;
23179 +       size_t size;
23180 +       size_t used;
23181 +       buffer_ptr_free_t free;
23182 +} buffer_ptr;
23183 +
23184 +typedef struct {
23185         buffer **ptr;
23186 -       
23187 +
23188         size_t used;
23189         size_t size;
23190  } buffer_array;
23191  
23192  typedef struct {
23193         char *ptr;
23194 -       
23195 -       size_t offset; /* input-pointer */
23196 -       
23197 -       size_t used;   /* output-pointer */
23198 +
23199 +       size_t offset; /* input pointer */
23200 +
23201 +       size_t used;   /* output pointer */
23202         size_t size;
23203  } read_buffer;
23204  
23205 +buffer_ptr *buffer_ptr_init(buffer_ptr_free_t freer);
23206 +void buffer_ptr_free(buffer_ptr *b);
23207 +void buffer_ptr_clear(buffer_ptr *b);
23208 +void buffer_ptr_append(buffer_ptr *b, void *item);
23209 +void *buffer_ptr_pop(buffer_ptr *b);
23210 +void *buffer_ptr_top(buffer_ptr *b);
23211 +
23212  buffer_array* buffer_array_init(void);
23213  void buffer_array_free(buffer_array *b);
23214  void buffer_array_reset(buffer_array *b);
23215 @@ -43,7 +60,7 @@
23216  buffer* buffer_init_string(const char *str);
23217  void buffer_free(buffer *b);
23218  void buffer_reset(buffer *b);
23219 -       
23220 +
23221  int buffer_prepare_copy(buffer *b, size_t size);
23222  int buffer_prepare_append(buffer *b, size_t size);
23223  
23224 @@ -85,9 +102,9 @@
23225  
23226  typedef enum {
23227         ENCODING_UNSET,
23228 -       ENCODING_REL_URI, /* for coding a rel-uri (/with space/and%percent) nicely as part of a href */
23229 -       ENCODING_REL_URI_PART, /* same as ENC_REL_URL plus coding / too as %2F */
23230 -       ENCODING_HTML,    /* & becomes &amp; and so on */
23231 +       ENCODING_REL_URI, /* for coding a rel-uri (/with space/and%percent) nicely as part of an href */
23232 +       ENCODING_REL_URI_PART, /* same as ENC_REL_URL plus encoding "/" as "%2F" */
23233 +       ENCODING_HTML,    /* "&" becomes "&amp;" and so on */
23234         ENCODING_MINIMAL_XML, /* minimal encoding for xml */
23235         ENCODING_HEX      /* encode string as hex */
23236  } buffer_encoding_t;
23237 @@ -111,19 +128,21 @@
23238  int light_isalpha(int c);
23239  int light_isalnum(int c);
23240  
23241 +#define BUFFER_CTYPE_FUNC(type) int buffer_is##type(buffer *b);
23242 +BUFFER_CTYPE_FUNC(digit)
23243 +BUFFER_CTYPE_FUNC(xdigit)
23244 +BUFFER_CTYPE_FUNC(alpha)
23245 +BUFFER_CTYPE_FUNC(alnum)
23246 +
23247  #define BUFFER_APPEND_STRING_CONST(x, y) \
23248         buffer_append_string_len(x, y, sizeof(y) - 1)
23249  
23250  #define BUFFER_COPY_STRING_CONST(x, y) \
23251         buffer_copy_string_len(x, y, sizeof(y) - 1)
23252  
23253 -#define BUFFER_APPEND_SLASH(x) \
23254 -       if (x->used > 1 && x->ptr[x->used - 2] != '/') { BUFFER_APPEND_STRING_CONST(x, "/"); }
23255 -
23256  #define CONST_STR_LEN(x) x, x ? sizeof(x) - 1 : 0
23257  #define CONST_BUF_LEN(x) x->ptr, x->used ? x->used - 1 : 0
23258  
23259 -
23260  #define SEGFAULT() do { fprintf(stderr, "%s.%d: aborted\n", __FILE__, __LINE__); abort(); } while(0)
23261  #define UNUSED(x) ( (void)(x) )
23262  
23263
23264 Property changes on: src/buffer.h
23265 ___________________________________________________________________
23266 Name: svn:eol-style
23267    + native
23268
23269 Index: src/mod_proxy.c
23270 ===================================================================
23271 --- src/mod_proxy.c     (.../tags/lighttpd-1.4.11)      (revision 1159)
23272 +++ src/mod_proxy.c     (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
23273 @@ -1,6 +1,5 @@
23274  #include <sys/types.h>
23275  
23276 -#include <unistd.h>
23277  #include <errno.h>
23278  #include <fcntl.h>
23279  #include <string.h>
23280 @@ -23,7 +22,10 @@
23281  
23282  #include "inet_ntop_cache.h"
23283  #include "crc32.h"
23284 +#include "network.h"
23285  
23286 +#include "http_resp.h"
23287 +
23288  #include <stdio.h>
23289  
23290  #ifdef HAVE_SYS_FILIO_H
23291 @@ -31,6 +33,8 @@
23292  #endif
23293  
23294  #include "sys-socket.h"
23295 +#include "sys-files.h"
23296 +#include "sys-strings.h"
23297  
23298  #define data_proxy data_fastcgi
23299  #define data_proxy_init data_fastcgi_init
23300 @@ -38,16 +42,16 @@
23301  #define PROXY_RETRY_TIMEOUT 60
23302  
23303  /**
23304 - * 
23305 - * the proxy module is based on the fastcgi module 
23306 - * 
23307 + *
23308 + * the proxy module is based on the fastcgi module
23309 + *
23310   * 28.06.2004 Jan Kneschke     The first release
23311   * 01.07.2004 Evgeny Rodichev  Several bugfixes and cleanups
23312   *            - co-ordinate up- and downstream flows correctly (proxy_demux_response
23313   *              and proxy_handle_fdevent)
23314   *            - correctly transfer upstream http_response_status;
23315   *            - some unused structures removed.
23316 - * 
23317 + *
23318   * TODO:      - delay upstream read if write_queue is too large
23319   *              (to prevent memory eating, like in apache). Shoud be
23320   *              configurable).
23321 @@ -66,26 +70,31 @@
23322         int debug;
23323  
23324         proxy_balance_t balance;
23325 +
23326 +       array *last_used_backends; /* "extension" : last_used_backend */
23327  } plugin_config;
23328  
23329  typedef struct {
23330         PLUGIN_DATA;
23331 -       
23332 +
23333         buffer *parse_response;
23334         buffer *balance_buf;
23335 -       
23336 +
23337 +       array *ignore_headers;
23338 +
23339         plugin_config **config_storage;
23340 -       
23341 +
23342         plugin_config conf;
23343  } plugin_data;
23344  
23345 -typedef enum { 
23346 -       PROXY_STATE_INIT, 
23347 -       PROXY_STATE_CONNECT, 
23348 -       PROXY_STATE_PREPARE_WRITE, 
23349 -       PROXY_STATE_WRITE, 
23350 -       PROXY_STATE_READ, 
23351 -       PROXY_STATE_ERROR 
23352 +typedef enum {
23353 +       PROXY_STATE_INIT,
23354 +       PROXY_STATE_CONNECT,
23355 +       PROXY_STATE_PREPARE_WRITE,
23356 +       PROXY_STATE_WRITE,
23357 +    PROXY_STATE_RESPONSE_HEADER,
23358 +    PROXY_STATE_RESPONSE_CONTENT,
23359 +       PROXY_STATE_ERROR
23360  } proxy_connection_state_t;
23361  
23362  enum { PROXY_STDOUT, PROXY_END_REQUEST };
23363 @@ -93,19 +102,20 @@
23364  typedef struct {
23365         proxy_connection_state_t state;
23366         time_t state_timestamp;
23367 -       
23368 +
23369         data_proxy *host;
23370 -       
23371 +
23372         buffer *response;
23373         buffer *response_header;
23374  
23375         chunkqueue *wb;
23376 -       
23377 +    chunkqueue *rb;
23378 +
23379         int fd; /* fd to the proxy process */
23380         int fde_ndx; /* index into the fd-event buffer */
23381  
23382         size_t path_info_offset; /* start of path_info in uri.path */
23383 -       
23384 +
23385         connection *remote_conn;  /* dump pointer */
23386         plugin_data *plugin_data; /* dump pointer */
23387  } handler_ctx;
23388 @@ -116,21 +126,22 @@
23389  
23390  static handler_ctx * handler_ctx_init() {
23391         handler_ctx * hctx;
23392 -       
23393  
23394 +
23395         hctx = calloc(1, sizeof(*hctx));
23396 -       
23397 +
23398         hctx->state = PROXY_STATE_INIT;
23399         hctx->host = NULL;
23400 -       
23401 +
23402         hctx->response = buffer_init();
23403         hctx->response_header = buffer_init();
23404  
23405         hctx->wb = chunkqueue_init();
23406 +    hctx->rb = chunkqueue_init();
23407  
23408         hctx->fd = -1;
23409         hctx->fde_ndx = -1;
23410 -       
23411 +
23412         return hctx;
23413  }
23414  
23415 @@ -138,47 +149,70 @@
23416         buffer_free(hctx->response);
23417         buffer_free(hctx->response_header);
23418         chunkqueue_free(hctx->wb);
23419 -       
23420 +    chunkqueue_free(hctx->rb);
23421 +
23422         free(hctx);
23423  }
23424  
23425  INIT_FUNC(mod_proxy_init) {
23426         plugin_data *p;
23427 -       
23428 +       size_t i;
23429 +
23430 +       char *hop2hop_headers[] = {
23431 +               "Connection",
23432 +               "Keep-Alive",
23433 +               "Host",
23434 +               NULL
23435 +       };
23436 +
23437         p = calloc(1, sizeof(*p));
23438 -       
23439 +
23440         p->parse_response = buffer_init();
23441         p->balance_buf = buffer_init();
23442 -       
23443 +       p->ignore_headers = array_init();
23444 +
23445 +       for (i = 0; hop2hop_headers[i]; i++) {
23446 +               data_string *ds;
23447 +
23448 +               if (NULL == (ds = (data_string *)array_get_unused_element(p->ignore_headers, TYPE_STRING))) {
23449 +                       ds = data_string_init();
23450 +               }
23451 +
23452 +               buffer_copy_string(ds->value, hop2hop_headers[i]);
23453 +               array_insert_unique(p->ignore_headers, (data_unset *)ds);
23454 +       }
23455 +
23456         return p;
23457  }
23458  
23459  
23460  FREE_FUNC(mod_proxy_free) {
23461         plugin_data *p = p_d;
23462 -       
23463 +
23464         UNUSED(srv);
23465  
23466         buffer_free(p->parse_response);
23467         buffer_free(p->balance_buf);
23468 -       
23469 +
23470         if (p->config_storage) {
23471                 size_t i;
23472                 for (i = 0; i < srv->config_context->used; i++) {
23473                         plugin_config *s = p->config_storage[i];
23474 -                       
23475 +
23476                         if (s) {
23477 -                       
23478                                 array_free(s->extensions);
23479 -                       
23480 +                               array_free(s->last_used_backends);
23481 +
23482                                 free(s);
23483                         }
23484                 }
23485                 free(p->config_storage);
23486         }
23487 -       
23488 +
23489 +       free(p->ignore_headers);
23490 +
23491         free(p);
23492 -       
23493 +
23494         return HANDLER_GO_ON;
23495  }
23496  
23497 @@ -186,37 +220,38 @@
23498         plugin_data *p = p_d;
23499         data_unset *du;
23500         size_t i = 0;
23501 -       
23502 -       config_values_t cv[] = { 
23503 +
23504 +       config_values_t cv[] = {
23505                 { "proxy.server",              NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
23506                 { "proxy.debug",               NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
23507                 { "proxy.balance",             NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },      /* 2 */
23508                 { NULL,                        NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
23509         };
23510 -       
23511 +
23512         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
23513 -       
23514 +
23515         for (i = 0; i < srv->config_context->used; i++) {
23516                 plugin_config *s;
23517                 array *ca;
23518 -               
23519 +
23520                 s = malloc(sizeof(plugin_config));
23521 -               s->extensions    = array_init();
23522 +               s->extensions         = array_init();
23523 +               s->last_used_backends = array_init();
23524                 s->debug         = 0;
23525 -               
23526 +
23527                 cv[0].destination = s->extensions;
23528                 cv[1].destination = &(s->debug);
23529                 cv[2].destination = p->balance_buf;
23530  
23531                 buffer_reset(p->balance_buf);
23532 -               
23533 +
23534                 p->config_storage[i] = s;
23535                 ca = ((data_config *)srv->config_context->data[i])->value;
23536 -       
23537 +
23538                 if (0 != config_insert_values_global(srv, ca, cv)) {
23539                         return HANDLER_ERROR;
23540                 }
23541 -       
23542 +
23543                 if (buffer_is_empty(p->balance_buf)) {
23544                         s->balance = PROXY_BALANCE_FAIR;
23545                 } else if (buffer_is_equal_string(p->balance_buf, CONST_STR_LEN("fair"))) {
23546 @@ -226,7 +261,7 @@
23547                 } else if (buffer_is_equal_string(p->balance_buf, CONST_STR_LEN("hash"))) {
23548                         s->balance = PROXY_BALANCE_HASH;
23549                 } else {
23550 -                       log_error_write(srv, __FILE__, __LINE__, "sb", 
23551 +                       log_error_write(srv, __FILE__, __LINE__, "sb",
23552                                         "proxy.balance has to be one of: fair, round-robin, hash, but not:", p->balance_buf);
23553                         return HANDLER_ERROR;
23554                 }
23555 @@ -234,91 +269,91 @@
23556                 if (NULL != (du = array_get_element(ca, "proxy.server"))) {
23557                         size_t j;
23558                         data_array *da = (data_array *)du;
23559 -                       
23560 +
23561                         if (du->type != TYPE_ARRAY) {
23562 -                               log_error_write(srv, __FILE__, __LINE__, "sss", 
23563 +                               log_error_write(srv, __FILE__, __LINE__, "sss",
23564                                                 "unexpected type for key: ", "proxy.server", "array of strings");
23565 -                               
23566 +
23567                                 return HANDLER_ERROR;
23568                         }
23569 -                       
23570 -                       /* 
23571 +
23572 +                       /*
23573                          * proxy.server = ( "<ext>" => ...,
23574                          *                  "<ext>" => ... )
23575                          */
23576 -                       
23577 +
23578                         for (j = 0; j < da->value->used; j++) {
23579                                 data_array *da_ext = (data_array *)da->value->data[j];
23580                                 size_t n;
23581 -                               
23582 +
23583                                 if (da_ext->type != TYPE_ARRAY) {
23584 -                                       log_error_write(srv, __FILE__, __LINE__, "sssbs", 
23585 -                                                       "unexpected type for key: ", "proxy.server", 
23586 +                                       log_error_write(srv, __FILE__, __LINE__, "sssbs",
23587 +                                                       "unexpected type for key: ", "proxy.server",
23588                                                         "[", da->value->data[j]->key, "](string)");
23589 -                                       
23590 +
23591                                         return HANDLER_ERROR;
23592                                 }
23593 -                               
23594 -                               /* 
23595 -                                * proxy.server = ( "<ext>" => 
23596 -                                *                     ( "<host>" => ( ... ), 
23597 +
23598 +                               /*
23599 +                                * proxy.server = ( "<ext>" =>
23600 +                                *                     ( "<host>" => ( ... ),
23601                                  *                       "<host>" => ( ... )
23602 -                                *                     ), 
23603 +                                *                     ),
23604                                  *                    "<ext>" => ... )
23605                                  */
23606 -                               
23607 +
23608                                 for (n = 0; n < da_ext->value->used; n++) {
23609                                         data_array *da_host = (data_array *)da_ext->value->data[n];
23610 -                                       
23611 +
23612                                         data_proxy *df;
23613                                         data_array *dfa;
23614 -                                       
23615 -                                       config_values_t pcv[] = { 
23616 +
23617 +                                       config_values_t pcv[] = {
23618                                                 { "host",              NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },      /* 0 */
23619                                                 { "port",              NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
23620                                                 { NULL,                NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
23621                                         };
23622 -                                       
23623 +
23624                                         if (da_host->type != TYPE_ARRAY) {
23625 -                                               log_error_write(srv, __FILE__, __LINE__, "ssSBS", 
23626 -                                                               "unexpected type for key:", 
23627 -                                                               "proxy.server", 
23628 +                                               log_error_write(srv, __FILE__, __LINE__, "ssSBS",
23629 +                                                               "unexpected type for key:",
23630 +                                                               "proxy.server",
23631                                                                 "[", da_ext->value->data[n]->key, "](string)");
23632 -                                               
23633 +
23634                                                 return HANDLER_ERROR;
23635                                         }
23636 -                                       
23637 +
23638                                         df = data_proxy_init();
23639 -                                       
23640 +
23641                                         df->port = 80;
23642 -                                       
23643 +
23644                                         buffer_copy_string_buffer(df->key, da_host->key);
23645 -                                       
23646 +
23647                                         pcv[0].destination = df->host;
23648                                         pcv[1].destination = &(df->port);
23649 -                                       
23650 +
23651                                         if (0 != config_insert_values_internal(srv, da_host->value, pcv)) {
23652                                                 return HANDLER_ERROR;
23653                                         }
23654 -                                       
23655 +
23656                                         if (buffer_is_empty(df->host)) {
23657 -                                               log_error_write(srv, __FILE__, __LINE__, "sbbbs", 
23658 -                                                               "missing key (string):", 
23659 +                                               log_error_write(srv, __FILE__, __LINE__, "sbbbs",
23660 +                                                               "missing key (string):",
23661                                                                 da->key,
23662                                                                 da_ext->key,
23663                                                                 da_host->key,
23664                                                                 "host");
23665 -                                               
23666 +
23667                                                 return HANDLER_ERROR;
23668                                         }
23669 -                                       
23670 +
23671                                         /* if extension already exists, take it */
23672 -                                       
23673 +
23674                                         if (NULL == (dfa = (data_array *)array_get_element(s->extensions, da_ext->key->ptr))) {
23675                                                 dfa = data_array_init();
23676 -                                               
23677 +
23678                                                 buffer_copy_string_buffer(dfa->key, da_ext->key);
23679 -                                               
23680 +
23681                                                 array_insert_unique(dfa->value, (data_unset *)df);
23682                                                 array_insert_unique(s->extensions, (data_unset *)dfa);
23683                                         } else {
23684 @@ -328,19 +363,19 @@
23685                         }
23686                 }
23687         }
23688 -       
23689 +
23690         return HANDLER_GO_ON;
23691  }
23692  
23693  void proxy_connection_close(server *srv, handler_ctx *hctx) {
23694         plugin_data *p;
23695         connection *con;
23696 -       
23697 +
23698         if (NULL == hctx) return;
23699 -       
23700 +
23701         p    = hctx->plugin_data;
23702         con  = hctx->remote_conn;
23703 -       
23704 +
23705         if (hctx->fd != -1) {
23706                 fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
23707                 fdevent_unregister(srv->ev, hctx->fd);
23708 @@ -348,47 +383,56 @@
23709                 close(hctx->fd);
23710                 srv->cur_fds--;
23711         }
23712 -       
23713 +
23714         handler_ctx_free(hctx);
23715 -       con->plugin_ctx[p->id] = NULL;  
23716 +       con->plugin_ctx[p->id] = NULL;
23717  }
23718  
23719  static int proxy_establish_connection(server *srv, handler_ctx *hctx) {
23720         struct sockaddr *proxy_addr;
23721         struct sockaddr_in proxy_addr_in;
23722         socklen_t servlen;
23723 -       
23724 +
23725         plugin_data *p    = hctx->plugin_data;
23726         data_proxy *host= hctx->host;
23727         int proxy_fd       = hctx->fd;
23728 -       
23729 +
23730         memset(&proxy_addr, 0, sizeof(proxy_addr));
23731 -       
23732 +
23733         proxy_addr_in.sin_family = AF_INET;
23734         proxy_addr_in.sin_addr.s_addr = inet_addr(host->host->ptr);
23735         proxy_addr_in.sin_port = htons(host->port);
23736         servlen = sizeof(proxy_addr_in);
23737 -               
23738 +
23739         proxy_addr = (struct sockaddr *) &proxy_addr_in;
23740 -       
23741 +
23742         if (-1 == connect(proxy_fd, proxy_addr, servlen)) {
23743 -               if (errno == EINPROGRESS || errno == EALREADY) {
23744 +#ifdef _WIN32
23745 +        errno = WSAGetLastError();
23746 +#endif
23747 +        switch(errno) {
23748 +#ifdef _WIN32
23749 +        case WSAEWOULDBLOCK:
23750 +#endif
23751 +        case EINPROGRESS:
23752 +        case EALREADY:
23753                         if (p->conf.debug) {
23754 -                               log_error_write(srv, __FILE__, __LINE__, "sd", 
23755 +                               log_error_write(srv, __FILE__, __LINE__, "sd",
23756                                                 "connect delayed:", proxy_fd);
23757                         }
23758 -                       
23759 +
23760                         return 1;
23761 -               } else {
23762 -                       
23763 -                       log_error_write(srv, __FILE__, __LINE__, "sdsd", 
23764 +               default:
23765 +
23766 +                       log_error_write(srv, __FILE__, __LINE__, "sdsd",
23767                                         "connect failed:", proxy_fd, strerror(errno), errno);
23768 -                       
23769 +
23770                         return -1;
23771                 }
23772         }
23773 +    fprintf(stderr, "%s.%d: connected fd = %d\r\n", __FILE__, __LINE__, proxy_fd);
23774         if (p->conf.debug) {
23775 -               log_error_write(srv, __FILE__, __LINE__, "sd", 
23776 +               log_error_write(srv, __FILE__, __LINE__, "sd",
23777                                 "connect succeeded: ", proxy_fd);
23778         }
23779  
23780 @@ -422,25 +466,26 @@
23781  
23782  static int proxy_create_env(server *srv, handler_ctx *hctx) {
23783         size_t i;
23784 -       
23785 +
23786         connection *con   = hctx->remote_conn;
23787 +       plugin_data *p    = hctx->plugin_data;
23788         buffer *b;
23789 -       
23790 +
23791         /* build header */
23792  
23793         b = chunkqueue_get_append_buffer(hctx->wb);
23794 -       
23795 +
23796         /* request line */
23797         buffer_copy_string(b, get_http_method_name(con->request.http_method));
23798         BUFFER_APPEND_STRING_CONST(b, " ");
23799 -       
23800 +
23801         buffer_append_string_buffer(b, con->request.uri);
23802         BUFFER_APPEND_STRING_CONST(b, " HTTP/1.0\r\n");
23803  
23804         proxy_append_header(con, "X-Forwarded-For", (char *)inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
23805 -       /* http_host is NOT is just a pointer to a buffer 
23806 +       /* http_host is NOT is just a pointer to a buffer
23807          * which is NULL if it is not set */
23808 -       if (con->request.http_host && 
23809 +       if (con->request.http_host &&
23810             !buffer_is_empty(con->request.http_host)) {
23811                 proxy_set_header(con, "X-Host", con->request.http_host->ptr);
23812         }
23813 @@ -449,24 +494,26 @@
23814         /* request header */
23815         for (i = 0; i < con->request.headers->used; i++) {
23816                 data_string *ds;
23817 -               
23818 +
23819                 ds = (data_string *)con->request.headers->data[i];
23820 -               
23821 +
23822                 if (ds->value->used && ds->key->used) {
23823 -                       if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Connection"))) continue;
23824 -                       
23825 +
23826 +                       /* don't copy hop-to-hop headers */
23827 +                       if (array_get_element(p->ignore_headers, ds->key->ptr)) continue;
23828 +
23829                         buffer_append_string_buffer(b, ds->key);
23830                         BUFFER_APPEND_STRING_CONST(b, ": ");
23831                         buffer_append_string_buffer(b, ds->value);
23832                         BUFFER_APPEND_STRING_CONST(b, "\r\n");
23833                 }
23834         }
23835 -       
23836 +
23837         BUFFER_APPEND_STRING_CONST(b, "\r\n");
23838 -       
23839 +
23840         hctx->wb->bytes_in += b->used - 1;
23841         /* body */
23842 -       
23843 +
23844         if (con->request.content_length) {
23845                 chunkqueue *req_cq = con->request_content_queue;
23846                 chunk *req_c;
23847 @@ -479,7 +526,7 @@
23848  
23849                         /* we announce toWrite octects
23850                          * now take all the request_content chunk that we need to fill this request
23851 -                        * */   
23852 +                        * */
23853  
23854                         switch (req_c->type) {
23855                         case FILE_CHUNK:
23856 @@ -507,223 +554,125 @@
23857  
23858                                 req_c->offset += weHave;
23859                                 req_cq->bytes_out += weHave;
23860 -                               
23861 +
23862                                 hctx->wb->bytes_in += weHave;
23863  
23864                                 break;
23865                         default:
23866                                 break;
23867                         }
23868 -                       
23869 +
23870                         offset += weHave;
23871                 }
23872  
23873         }
23874 -       
23875 +
23876         return 0;
23877  }
23878  
23879  static int proxy_set_state(server *srv, handler_ctx *hctx, proxy_connection_state_t state) {
23880         hctx->state = state;
23881         hctx->state_timestamp = srv->cur_ts;
23882 -       
23883 +
23884         return 0;
23885  }
23886  
23887  
23888 -static int proxy_response_parse(server *srv, connection *con, plugin_data *p, buffer *in) {
23889 -       char *s, *ns;
23890 -       int http_response_status = -1;
23891 -       
23892 -       UNUSED(srv);
23893 +static void chunkqueue_print(chunkqueue *cq) {
23894 +    chunk *c;
23895  
23896 -       /* \r\n -> \0\0 */
23897 -       
23898 -       buffer_copy_string_buffer(p->parse_response, in);
23899 -       
23900 -       for (s = p->parse_response->ptr; NULL != (ns = strstr(s, "\r\n")); s = ns + 2) {
23901 -               char *key, *value;
23902 -               int key_len;
23903 -               data_string *ds;
23904 -               int copy_header;
23905 -               
23906 -               ns[0] = '\0';
23907 -               ns[1] = '\0';
23908 +    for (c = cq->first; c; c = c->next) {
23909 +        fprintf(stderr, "%s", c->mem->ptr + c->offset);
23910 +    }
23911 +    fprintf(stderr, "\r\n");
23912 +}
23913  
23914 -               if (-1 == http_response_status) {
23915 -                       /* The first line of a Response message is the Status-Line */
23916 +static int proxy_demux_response(server *srv, handler_ctx *hctx) {
23917 +       plugin_data *p    = hctx->plugin_data;
23918 +       connection *con   = hctx->remote_conn;
23919 +       int proxy_fd       = hctx->fd;
23920 +    chunkqueue *next_queue = NULL;
23921 +    chunk *c = NULL;
23922  
23923 -                       for (key=s; *key && *key != ' '; key++);
23924 +    switch(srv->network_backend_read(srv, con, proxy_fd, hctx->rb)) {
23925 +    case NETWORK_STATUS_SUCCESS:
23926 +        /* we got content */
23927 +        break;
23928 +    case NETWORK_STATUS_CONNECTION_CLOSE:
23929 +        /* we are done, get out of here */
23930 +               con->file_finished = 1;
23931  
23932 -                       if (*key) {
23933 -                               http_response_status = (int) strtol(key, NULL, 10);
23934 -                               if (http_response_status <= 0) http_response_status = 502;
23935 -                       } else {
23936 -                               http_response_status = 502;
23937 -                       }
23938 +        /* close the chunk-queue with a empty chunk */
23939 +               http_chunk_append_mem(srv, con, NULL, 0);
23940 +               joblist_append(srv, con);
23941  
23942 -                       con->http_status = http_response_status;
23943 -                       con->parsed_response |= HTTP_STATUS;
23944 -                       continue;
23945 -               }
23946 -               
23947 -               if (NULL == (value = strchr(s, ':'))) {
23948 -                       /* now we expect: "<key>: <value>\n" */
23949 +        return 1;
23950 +    default:
23951 +        /* oops */
23952 +        return -1;
23953 +    }
23954  
23955 -                       continue;
23956 -               }
23957 +    /* looks like we got some content
23958 +    *
23959 +    * split off the header from the incoming stream
23960 +    */
23961  
23962 -               key = s;
23963 -               key_len = value - key;
23964 -               
23965 -               value++;
23966 -               /* strip WS */
23967 -               while (*value == ' ' || *value == '\t') value++;
23968 -               
23969 -               copy_header = 1;
23970 -               
23971 -               switch(key_len) {
23972 -               case 4:
23973 -                       if (0 == strncasecmp(key, "Date", key_len)) {
23974 -                               con->parsed_response |= HTTP_DATE;
23975 -                       }
23976 -                       break;
23977 -               case 8:
23978 -                       if (0 == strncasecmp(key, "Location", key_len)) {
23979 -                               con->parsed_response |= HTTP_LOCATION;
23980 -                       }
23981 -                       break;
23982 -               case 10:
23983 -                       if (0 == strncasecmp(key, "Connection", key_len)) {
23984 -                               copy_header = 0;
23985 -                       }
23986 -                       break;
23987 -               case 14:
23988 -                       if (0 == strncasecmp(key, "Content-Length", key_len)) {
23989 -                               con->response.content_length = strtol(value, NULL, 10);
23990 -                               con->parsed_response |= HTTP_CONTENT_LENGTH;
23991 -                       }
23992 -                       break;
23993 -               default:
23994 -                       break;
23995 -               }
23996 +    if (hctx->state == PROXY_STATE_RESPONSE_HEADER) {
23997 +        http_resp *resp = http_response_init();
23998  
23999 -               if (copy_header) {
24000 -                       if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
24001 -                               ds = data_response_init();
24002 -                       }
24003 -                       buffer_copy_string_len(ds->key, key, key_len);
24004 -                       buffer_copy_string(ds->value, value);
24005 -                       
24006 -                       array_insert_unique(con->response.headers, (data_unset *)ds);
24007 -               }
24008 -       }
24009 -       
24010 -       return 0;
24011 -}
24012 +        /* the response header is not fully received yet,
24013 +        *
24014 +        * extract the http-response header from the rb-cq
24015 +        */
24016 +        fprintf(stderr, "%s.%d: network-read\r\n", __FILE__, __LINE__);
24017 +        chunkqueue_print(hctx->rb);
24018  
24019 +        switch (http_response_parse_cq(hctx->rb, resp)) {
24020 +        case PARSE_ERROR:
24021 +            /* parsing failed */
24022  
24023 -static int proxy_demux_response(server *srv, handler_ctx *hctx) {
24024 -       int fin = 0;
24025 -       int b;
24026 -       ssize_t r;
24027 -       
24028 -       plugin_data *p    = hctx->plugin_data;
24029 -       connection *con   = hctx->remote_conn;
24030 -       int proxy_fd       = hctx->fd;
24031 -       
24032 -       /* check how much we have to read */
24033 -       if (ioctl(hctx->fd, FIONREAD, &b)) {
24034 -               log_error_write(srv, __FILE__, __LINE__, "sd", 
24035 -                               "ioctl failed: ",
24036 -                               proxy_fd);
24037 -               return -1;
24038 -       }
24039 +            con->http_status = 502; /* Bad Gateway */
24040 +            return 1;
24041 +        case PARSE_NEED_MORE:
24042 +            return 0;
24043 +        case PARSE_SUCCESS:
24044 +            con->http_status = resp->status;
24045  
24046 +            fprintf(stderr, "%s.%d: parsing done\r\n", __FILE__, __LINE__);
24047 +            chunkqueue_print(hctx->rb);
24048  
24049 -       if (p->conf.debug) {
24050 -               log_error_write(srv, __FILE__, __LINE__, "sd",
24051 -                              "proxy - have to read:", b);
24052 -       }
24053 +            con->file_started = 1;
24054  
24055 -       if (b > 0) {
24056 -               if (hctx->response->used == 0) {
24057 -                       /* avoid too small buffer */
24058 -                       buffer_prepare_append(hctx->response, b + 1);
24059 -                       hctx->response->used = 1;
24060 -               } else {
24061 -                       buffer_prepare_append(hctx->response, hctx->response->used + b);
24062 -               }
24063 -               
24064 -               if (-1 == (r = read(hctx->fd, hctx->response->ptr + hctx->response->used - 1, b))) {
24065 -                       log_error_write(srv, __FILE__, __LINE__, "sds", 
24066 -                                       "unexpected end-of-file (perhaps the proxy process died):",
24067 -                                       proxy_fd, strerror(errno));
24068 -                       return -1;
24069 -               }
24070 -               
24071 -               /* this should be catched by the b > 0 above */
24072 -               assert(r);
24073 -               
24074 -               hctx->response->used += r;
24075 -               hctx->response->ptr[hctx->response->used - 1] = '\0';
24076 +            hctx->state = PROXY_STATE_RESPONSE_CONTENT;
24077 +            break;
24078 +        }
24079 +    }
24080  
24081 -#if 0
24082 -               log_error_write(srv, __FILE__, __LINE__, "sdsbs", 
24083 -                               "demux: Response buffer len", hctx->response->used, ":", hctx->response, ":");
24084 -#endif
24085 +    /* FIXME: pass the response-header to the other plugins to
24086 +    * setup the filter-queue
24087 +    *
24088 +    * - use next-queue instead of con->write_queue
24089 +    */
24090  
24091 -               if (0 == con->got_response) {
24092 -                       con->got_response = 1;
24093 -                       buffer_prepare_copy(hctx->response_header, 128);
24094 -               }
24095 -                               
24096 -               if (0 == con->file_started) {
24097 -                       char *c;
24098 -                               
24099 -                       /* search for the \r\n\r\n in the string */
24100 -                       if (NULL != (c = buffer_search_string_len(hctx->response, "\r\n\r\n", 4))) {
24101 -                               size_t hlen = c - hctx->response->ptr + 4;
24102 -                               size_t blen = hctx->response->used - hlen - 1;
24103 -                               /* found */
24104 -                               
24105 -                               buffer_append_string_len(hctx->response_header, hctx->response->ptr, c - hctx->response->ptr + 4);
24106 -#if 0
24107 -                               log_error_write(srv, __FILE__, __LINE__, "sb", "Header:", hctx->response_header);
24108 -#endif
24109 -                               /* parse the response header */
24110 -                               proxy_response_parse(srv, con, p, hctx->response_header);
24111 -                                       
24112 -                               /* enable chunked-transfer-encoding */
24113 -                               if (con->request.http_version == HTTP_VERSION_1_1 &&
24114 -                                   !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
24115 -                                       con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
24116 -                               }
24117 -                                       
24118 -                               con->file_started = 1;
24119 -                               if (blen) {
24120 -                                       http_chunk_append_mem(srv, con, c + 4, blen + 1);
24121 -                                       joblist_append(srv, con);
24122 -                               }
24123 -                               hctx->response->used = 0;
24124 -                       }
24125 -               } else {
24126 -                       http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used);
24127 -                       joblist_append(srv, con);
24128 -                       hctx->response->used = 0;
24129 -               }
24130 -               
24131 -       } else {
24132 -               /* reading from upstream done */
24133 -               con->file_finished = 1;
24134 -               
24135 -               http_chunk_append_mem(srv, con, NULL, 0);
24136 -               joblist_append(srv, con);
24137 -               
24138 -               fin = 1;
24139 +    next_queue = con->write_queue;
24140 +
24141 +    assert(hctx->state == PROXY_STATE_RESPONSE_CONTENT);
24142 +
24143 +    /* FIXME: if we have a content-length or chunked-encoding
24144 +    * handle it.
24145 +    *
24146 +    * for now we wait for EOF on the socket */
24147 +
24148 +    /* copy the content to the next cq */
24149 +    for (c = hctx->rb->first; c; c = c->next) {
24150 +        http_chunk_append_mem(srv, con, c->mem->ptr + c->offset, c->mem->used - c->offset);
24151 +
24152 +        c->offset = c->mem->used - 1;
24153         }
24154 -       
24155 -       return fin;
24156 +
24157 +    chunkqueue_remove_finished_chunks(hctx->rb);
24158 +
24159 +       return 0;
24160  }
24161  
24162  
24163 @@ -731,12 +680,12 @@
24164         data_proxy *host= hctx->host;
24165         plugin_data *p    = hctx->plugin_data;
24166         connection *con   = hctx->remote_conn;
24167 -       
24168 +
24169         int ret;
24170 -       
24171 -       if (!host || 
24172 +
24173 +       if (!host ||
24174             (!host->host->used || !host->port)) return -1;
24175 -       
24176 +
24177         switch(hctx->state) {
24178         case PROXY_STATE_INIT:
24179                 if (-1 == (hctx->fd = socket(AF_INET, SOCK_STREAM, 0))) {
24180 @@ -744,19 +693,19 @@
24181                         return HANDLER_ERROR;
24182                 }
24183                 hctx->fde_ndx = -1;
24184 -               
24185 +
24186                 srv->cur_fds++;
24187 -               
24188 +
24189                 fdevent_register(srv->ev, hctx->fd, proxy_handle_fdevent, hctx);
24190 -               
24191 +
24192                 if (-1 == fdevent_fcntl_set(srv->ev, hctx->fd)) {
24193                         log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed: ", strerror(errno));
24194 -                       
24195 +
24196                         return HANDLER_ERROR;
24197                 }
24198 -               
24199 +
24200                 /* fall through */
24201 -               
24202 +
24203         case PROXY_STATE_CONNECT:
24204                 /* try to finish the connect() */
24205                 if (hctx->state == PROXY_STATE_INIT) {
24206 @@ -764,16 +713,16 @@
24207                         switch (proxy_establish_connection(srv, hctx)) {
24208                         case 1:
24209                                 proxy_set_state(srv, hctx, PROXY_STATE_CONNECT);
24210 -                               
24211 +
24212                                 /* connection is in progress, wait for an event and call getsockopt() below */
24213 -                               
24214 +
24215                                 fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
24216 -                               
24217 +
24218                                 return HANDLER_WAIT_FOR_EVENT;
24219                         case -1:
24220                                 /* if ECONNREFUSED choose another connection -> FIXME */
24221                                 hctx->fde_ndx = -1;
24222 -                               
24223 +
24224                                 return HANDLER_ERROR;
24225                         default:
24226                                 /* everything is ok, go on */
24227 @@ -782,152 +731,152 @@
24228                 } else {
24229                         int socket_error;
24230                         socklen_t socket_error_len = sizeof(socket_error);
24231 -               
24232 -                       /* we don't need it anymore */  
24233 +
24234 +                       /* we don't need it anymore */
24235                         fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
24236  
24237                         /* try to finish the connect() */
24238                         if (0 != getsockopt(hctx->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) {
24239 -                               log_error_write(srv, __FILE__, __LINE__, "ss", 
24240 +                               log_error_write(srv, __FILE__, __LINE__, "ss",
24241                                                 "getsockopt failed:", strerror(errno));
24242 -                               
24243 +
24244                                 return HANDLER_ERROR;
24245                         }
24246                         if (socket_error != 0) {
24247                                 log_error_write(srv, __FILE__, __LINE__, "ss",
24248 -                                               "establishing connection failed:", strerror(socket_error), 
24249 +                                               "establishing connection failed:", strerror(socket_error),
24250                                                 "port:", hctx->host->port);
24251 -                               
24252 +
24253                                 return HANDLER_ERROR;
24254                         }
24255                         if (p->conf.debug) {
24256 -                               log_error_write(srv, __FILE__, __LINE__,  "s", "proxy - connect - delayed success"); 
24257 +                               log_error_write(srv, __FILE__, __LINE__,  "s", "proxy - connect - delayed success");
24258                         }
24259 +            fprintf(stderr, "%s.%d: connected fd = %d\r\n", __FILE__, __LINE__, hctx->fd);
24260                 }
24261 -               
24262 +
24263                 proxy_set_state(srv, hctx, PROXY_STATE_PREPARE_WRITE);
24264                 /* fall through */
24265         case PROXY_STATE_PREPARE_WRITE:
24266                 proxy_create_env(srv, hctx);
24267 -               
24268 +
24269                 proxy_set_state(srv, hctx, PROXY_STATE_WRITE);
24270 -               
24271 +
24272                 /* fall through */
24273         case PROXY_STATE_WRITE:;
24274 -               ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb); 
24275 +               ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb);
24276  
24277                 chunkqueue_remove_finished_chunks(hctx->wb);
24278  
24279 -               if (-1 == ret) {
24280 -                       if (errno != EAGAIN &&
24281 -                           errno != EINTR) {
24282 -                               log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed:", strerror(errno), errno);
24283 -                               
24284 -                               return HANDLER_ERROR;
24285 -                       } else {
24286 -                               fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
24287 +               switch(ret) {
24288 +        case NETWORK_STATUS_FATAL_ERROR:
24289 +                       log_error_write(srv, __FILE__, __LINE__, "ssd", "write failed:", strerror(errno), errno);
24290  
24291 -                               return HANDLER_WAIT_FOR_EVENT;
24292 -                       }
24293 +                       return HANDLER_ERROR;
24294 +        case NETWORK_STATUS_WAIT_FOR_EVENT:
24295 +
24296 +                       fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
24297 +
24298 +                       return HANDLER_WAIT_FOR_EVENT;
24299                 }
24300  
24301                 if (hctx->wb->bytes_out == hctx->wb->bytes_in) {
24302 -                       proxy_set_state(srv, hctx, PROXY_STATE_READ);
24303 +                       proxy_set_state(srv, hctx, PROXY_STATE_RESPONSE_HEADER);
24304  
24305                         fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
24306                         fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
24307                 } else {
24308                         fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
24309 -                               
24310 +
24311                         return HANDLER_WAIT_FOR_EVENT;
24312                 }
24313 -               
24314 +
24315                 return HANDLER_WAIT_FOR_EVENT;
24316 -       case PROXY_STATE_READ:
24317 +       case PROXY_STATE_RESPONSE_HEADER:
24318                 /* waiting for a response */
24319 +
24320                 return HANDLER_WAIT_FOR_EVENT;
24321         default:
24322                 log_error_write(srv, __FILE__, __LINE__, "s", "(debug) unknown state");
24323                 return HANDLER_ERROR;
24324         }
24325 -       
24326 +
24327         return HANDLER_GO_ON;
24328  }
24329  
24330 -#define PATCH(x) \
24331 -       p->conf.x = s->x;
24332  static int mod_proxy_patch_connection(server *srv, connection *con, plugin_data *p) {
24333         size_t i, j;
24334         plugin_config *s = p->config_storage[0];
24335 -       
24336 -       PATCH(extensions);
24337 -       PATCH(debug);
24338 -       PATCH(balance);
24339 -       
24340 +
24341 +       PATCH_OPTION(extensions);
24342 +       PATCH_OPTION(debug);
24343 +       PATCH_OPTION(balance);
24344 +       PATCH_OPTION(last_used_backends);
24345 +
24346         /* skip the first, the global context */
24347         for (i = 1; i < srv->config_context->used; i++) {
24348                 data_config *dc = (data_config *)srv->config_context->data[i];
24349                 s = p->config_storage[i];
24350 -               
24351 +
24352                 /* condition didn't match */
24353                 if (!config_check_cond(srv, con, dc)) continue;
24354 -               
24355 +
24356                 /* merge config */
24357                 for (j = 0; j < dc->value->used; j++) {
24358                         data_unset *du = dc->value->data[j];
24359 -                       
24360 +
24361                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.server"))) {
24362 -                               PATCH(extensions);
24363 +                               PATCH_OPTION(extensions);
24364                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.debug"))) {
24365 -                               PATCH(debug);
24366 +                               PATCH_OPTION(debug);
24367                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.balance"))) {
24368 -                               PATCH(balance);
24369 +                               PATCH_OPTION(balance);
24370 +                               PATCH_OPTION(last_used_backends);
24371                         }
24372                 }
24373         }
24374 -       
24375 +
24376         return 0;
24377  }
24378 -#undef PATCH
24379  
24380  SUBREQUEST_FUNC(mod_proxy_handle_subrequest) {
24381         plugin_data *p = p_d;
24382 -       
24383 +
24384         handler_ctx *hctx = con->plugin_ctx[p->id];
24385         data_proxy *host;
24386 -       
24387 +
24388         if (NULL == hctx) return HANDLER_GO_ON;
24389  
24390         mod_proxy_patch_connection(srv, con, p);
24391 -       
24392 +
24393         host = hctx->host;
24394 -       
24395 +
24396         /* not my job */
24397         if (con->mode != p->id) return HANDLER_GO_ON;
24398 -       
24399 +
24400         /* ok, create the request */
24401         switch(proxy_write_request(srv, hctx)) {
24402         case HANDLER_ERROR:
24403 -               log_error_write(srv, __FILE__, __LINE__,  "sbdd", "proxy-server disabled:", 
24404 +               log_error_write(srv, __FILE__, __LINE__,  "sbdd", "proxy-server disabled:",
24405                                 host->host,
24406                                 host->port,
24407                                 hctx->fd);
24408 -               
24409 +
24410                 /* disable this server */
24411                 host->is_disabled = 1;
24412                 host->disable_ts = srv->cur_ts;
24413 -               
24414 +
24415                 proxy_connection_close(srv, hctx);
24416 -       
24417 -               /* reset the enviroment and restart the sub-request */  
24418 +
24419 +               /* reset the enviroment and restart the sub-request */
24420                 buffer_reset(con->physical.path);
24421                 con->mode = DIRECT;
24422  
24423                 joblist_append(srv, con);
24424  
24425 -               /* mis-using HANDLER_WAIT_FOR_FD to break out of the loop 
24426 -                * and hope that the childs will be restarted 
24427 -                * 
24428 +               /* mis-using HANDLER_WAIT_FOR_FD to break out of the loop
24429 +                * and hope that the childs will be restarted
24430 +                *
24431                  */
24432  
24433                 return HANDLER_WAIT_FOR_FD;
24434 @@ -938,7 +887,7 @@
24435         default:
24436                 break;
24437         }
24438 -       
24439 +
24440         if (con->file_started == 1) {
24441                 return HANDLER_FINISHED;
24442         } else {
24443 @@ -951,13 +900,14 @@
24444         handler_ctx *hctx = ctx;
24445         connection  *con  = hctx->remote_conn;
24446         plugin_data *p    = hctx->plugin_data;
24447 -       
24448 -       
24449 +
24450 +
24451         if ((revents & FDEVENT_IN) &&
24452 -           hctx->state == PROXY_STATE_READ) {
24453 +        (hctx->state == PROXY_STATE_RESPONSE_HEADER ||
24454 +         hctx->state == PROXY_STATE_RESPONSE_CONTENT)) {
24455  
24456                 if (p->conf.debug) {
24457 -                       log_error_write(srv, __FILE__, __LINE__, "sd", 
24458 +                       log_error_write(srv, __FILE__, __LINE__, "sd",
24459                                         "proxy: fdevent-in", hctx->state);
24460                 }
24461  
24462 @@ -966,10 +916,10 @@
24463                         break;
24464                 case 1:
24465                         hctx->host->usage--;
24466 -                       
24467 +
24468                         /* we are done */
24469                         proxy_connection_close(srv, hctx);
24470 -                       
24471 +
24472                         joblist_append(srv, con);
24473                         return HANDLER_FINISHED;
24474                 case -1:
24475 @@ -982,53 +932,53 @@
24476                                 /* response might have been already started, kill the connection */
24477                                 connection_set_state(srv, con, CON_STATE_ERROR);
24478                         }
24479 -                       
24480 +
24481                         joblist_append(srv, con);
24482                         return HANDLER_FINISHED;
24483                 }
24484         }
24485 -       
24486 +
24487         if (revents & FDEVENT_OUT) {
24488                 if (p->conf.debug) {
24489 -                       log_error_write(srv, __FILE__, __LINE__, "sd", 
24490 +                       log_error_write(srv, __FILE__, __LINE__, "sd",
24491                                         "proxy: fdevent-out", hctx->state);
24492                 }
24493  
24494                 if (hctx->state == PROXY_STATE_CONNECT ||
24495                     hctx->state == PROXY_STATE_WRITE) {
24496                         /* we are allowed to send something out
24497 -                        * 
24498 +                        *
24499                          * 1. in a unfinished connect() call
24500                          * 2. in a unfinished write() call (long POST request)
24501                          */
24502                         return mod_proxy_handle_subrequest(srv, con, p);
24503                 } else {
24504 -                       log_error_write(srv, __FILE__, __LINE__, "sd", 
24505 +                       log_error_write(srv, __FILE__, __LINE__, "sd",
24506                                         "proxy: out", hctx->state);
24507                 }
24508         }
24509 -       
24510 +
24511         /* perhaps this issue is already handled */
24512         if (revents & FDEVENT_HUP) {
24513                 if (p->conf.debug) {
24514 -                       log_error_write(srv, __FILE__, __LINE__, "sd", 
24515 +                       log_error_write(srv, __FILE__, __LINE__, "sd",
24516                                         "proxy: fdevent-hup", hctx->state);
24517                 }
24518 -               
24519 +
24520                 if (hctx->state == PROXY_STATE_CONNECT) {
24521                         /* connect() -> EINPROGRESS -> HUP */
24522 -                       
24523 +
24524                         /**
24525 -                        * what is proxy is doing if it can't reach the next hop ? 
24526 -                        * 
24527 +                        * what is proxy is doing if it can't reach the next hop ?
24528 +                        *
24529                          */
24530 -                       
24531 +
24532                         proxy_connection_close(srv, hctx);
24533                         joblist_append(srv, con);
24534 -                       
24535 +
24536                         con->http_status = 503;
24537                         con->mode = DIRECT;
24538 -                       
24539 +
24540                         return HANDLER_FINISHED;
24541                 }
24542  
24543 @@ -1038,13 +988,13 @@
24544                 joblist_append(srv, con);
24545         } else if (revents & FDEVENT_ERR) {
24546                 /* kill all connections to the proxy process */
24547 -               
24548 +
24549                 log_error_write(srv, __FILE__, __LINE__, "sd", "proxy-FDEVENT_ERR, but no HUP", revents);
24550  
24551                 joblist_append(srv, con);
24552                 proxy_connection_close(srv, hctx);
24553         }
24554 -       
24555 +
24556         return HANDLER_FINISHED;
24557  }
24558  
24559 @@ -1058,44 +1008,49 @@
24560         buffer *fn;
24561         data_array *extension = NULL;
24562         size_t path_info_offset;
24563 -       
24564 +       data_integer *last_used_backend;
24565 +       data_proxy *host = NULL;
24566 +       handler_ctx *hctx = NULL;
24567 +
24568 +       array *backends = NULL;
24569 +
24570         /* Possibly, we processed already this request */
24571         if (con->file_started == 1) return HANDLER_GO_ON;
24572 -       
24573 +
24574         mod_proxy_patch_connection(srv, con, p);
24575 -       
24576 +
24577         fn = con->uri.path;
24578  
24579         if (fn->used == 0) {
24580                 return HANDLER_ERROR;
24581         }
24582 -       
24583 +
24584         s_len = fn->used - 1;
24585 -       
24586 -       
24587 +
24588 +
24589         path_info_offset = 0;
24590  
24591 -       if (p->conf.debug) {    
24592 +       if (p->conf.debug) {
24593                 log_error_write(srv, __FILE__, __LINE__,  "s", "proxy - start");
24594         }
24595  
24596         /* check if extension matches */
24597         for (k = 0; k < p->conf.extensions->used; k++) {
24598                 size_t ct_len;
24599 -               
24600 +
24601                 extension = (data_array *)p->conf.extensions->data[k];
24602 -               
24603 +
24604                 if (extension->key->used == 0) continue;
24605 -               
24606 +
24607                 ct_len = extension->key->used - 1;
24608 -               
24609 +
24610                 if (s_len < ct_len) continue;
24611 -               
24612 +
24613                 /* check extension in the form "/proxy_pattern" */
24614                 if (*(extension->key->ptr) == '/' && strncmp(fn->ptr, extension->key->ptr, ct_len) == 0) {
24615                         if (s_len > ct_len + 1) {
24616                                 char *pi_offset;
24617 -                               
24618 +
24619                                 if (0 != (pi_offset = strchr(fn->ptr + ct_len + 1, '/'))) {
24620                                         path_info_offset = pi_offset - fn->ptr;
24621                                 }
24622 @@ -1106,12 +1061,14 @@
24623                         break;
24624                 }
24625         }
24626 -       
24627 +
24628         if (k == p->conf.extensions->used) {
24629                 return HANDLER_GO_ON;
24630         }
24631  
24632 -       if (p->conf.debug) {    
24633 +       backends = extension->value;
24634 +
24635 +       if (p->conf.debug) {
24636                 log_error_write(srv, __FILE__, __LINE__,  "s", "proxy - ext found");
24637         }
24638  
24639 @@ -1120,34 +1077,34 @@
24640                 /* hash balancing */
24641  
24642                 if (p->conf.debug) {
24643 -                       log_error_write(srv, __FILE__, __LINE__,  "sd", 
24644 -                                       "proxy - used hash balancing, hosts:", extension->value->used);
24645 +                       log_error_write(srv, __FILE__, __LINE__,  "sd",
24646 +                                       "proxy - used hash balancing, hosts:", backends->used);
24647                 }
24648  
24649 -               for (k = 0, ndx = -1, last_max = ULONG_MAX; k < extension->value->used; k++) {
24650 -                       data_proxy *host = (data_proxy *)extension->value->data[k];
24651 +               for (k = 0, ndx = -1, last_max = ULONG_MAX; k < backends->used; k++) {
24652                         unsigned long cur_max;
24653  
24654 -                       if (host->is_disabled) continue;
24655 -                       
24656 +                       data_proxy *cur = (data_proxy *)backends->data[k];
24657 +
24658 +                       if (cur->is_disabled) continue;
24659 +
24660                         cur_max = generate_crc32c(CONST_BUF_LEN(con->uri.path)) +
24661 -                               generate_crc32c(CONST_BUF_LEN(host->host)) + /* we can cache this */
24662 +                               generate_crc32c(CONST_BUF_LEN(cur->host)) + /* we can cache this */
24663                                 generate_crc32c(CONST_BUF_LEN(con->uri.authority));
24664 -                       
24665 +
24666                         if (p->conf.debug) {
24667 -                               log_error_write(srv, __FILE__, __LINE__,  "sbbbd", 
24668 +                               log_error_write(srv, __FILE__, __LINE__,  "sbbbd",
24669                                                 "proxy - election:",
24670                                                 con->uri.path,
24671 -                                               host->host,
24672 +                                               cur->host,
24673                                                 con->uri.authority,
24674                                                 cur_max);
24675                         }
24676  
24677 -                       if ((last_max == ULONG_MAX) || /* first round */
24678 -                           (cur_max > last_max)) {
24679 +                       if (host == NULL || (cur_max > last_max)) {
24680                                 last_max = cur_max;
24681  
24682 -                               ndx = k;
24683 +                               host = cur;
24684                         }
24685                 }
24686  
24687 @@ -1155,19 +1112,20 @@
24688         case PROXY_BALANCE_FAIR:
24689                 /* fair balancing */
24690                 if (p->conf.debug) {
24691 -                       log_error_write(srv, __FILE__, __LINE__,  "s", 
24692 +                       log_error_write(srv, __FILE__, __LINE__,  "s",
24693                                         "proxy - used fair balancing");
24694                 }
24695  
24696 -               for (k = 0, ndx = -1, max_usage = INT_MAX; k < extension->value->used; k++) {
24697 -                       data_proxy *host = (data_proxy *)extension->value->data[k];
24698 -               
24699 -                       if (host->is_disabled) continue;
24700 +               /* try to find the host with the lowest load */
24701 +               for (k = 0, max_usage = 0; k < backends->used; k++) {
24702 +                       data_proxy *cur = (data_proxy *)backends->data[k];
24703  
24704 -                       if (host->usage < max_usage) {
24705 -                               max_usage = host->usage;
24706 -                       
24707 -                               ndx = k;
24708 +                       if (cur->is_disabled) continue;
24709 +
24710 +                       if (NULL == host || cur->usage < max_usage) {
24711 +                               max_usage = cur->usage;
24712 +
24713 +                               host = cur;
24714                         }
24715                 }
24716  
24717 @@ -1175,89 +1133,100 @@
24718         case PROXY_BALANCE_RR:
24719                 /* round robin */
24720                 if (p->conf.debug) {
24721 -                       log_error_write(srv, __FILE__, __LINE__,  "s", 
24722 +                       log_error_write(srv, __FILE__, __LINE__,  "s",
24723                                         "proxy - used round-robin balancing");
24724                 }
24725  
24726                 /* just to be sure */
24727 -               assert(extension->value->used < INT_MAX);
24728 -               
24729 -               for (k = 0, ndx = -1, max_usage = INT_MAX; k < extension->value->used; k++) {
24730 -                       data_proxy *host = (data_proxy *)extension->value->data[k];
24731 -               
24732 -                       if (host->is_disabled) continue;
24733 +               assert(backends->used < INT_MAX);
24734  
24735 -                       /* first usable ndx */
24736 -                       if (max_usage == INT_MAX) {
24737 -                               max_usage = k;
24738 -                       }
24739 +               /* send each request to another host:
24740 +                *
24741 +                * e.g.:
24742 +                *
24743 +                * if we have three hosts it is
24744 +                *
24745 +                * 1 .. 2 .. 3 .. 1 .. 2 .. 3
24746 +                *
24747 +                **/
24748  
24749 -                       /* get next ndx */
24750 -                       if ((int)k > host->last_used_ndx) {
24751 -                               ndx = k;
24752 -                               host->last_used_ndx = k;
24753 +               /* walk through the list */
24754 +               last_used_backend = (data_integer *)array_get_element(p->conf.last_used_backends, extension->key->ptr);
24755  
24756 -                               break;
24757 -                       }
24758 +               if (NULL == last_used_backend) {
24759 +                       last_used_backend = data_integer_init();
24760 +
24761 +                       buffer_copy_string_buffer(last_used_backend->key, extension->key);
24762 +                       last_used_backend->value = 0;
24763 +
24764 +                       array_insert_unique(p->conf.last_used_backends, (data_unset *)last_used_backend);
24765                 }
24766 -               
24767 -               /* didn't found a higher id, wrap to the start */
24768 -               if (ndx != -1 && max_usage != INT_MAX) {
24769 -                       ndx = max_usage;
24770 +
24771 +               /* scan all but the last host to see if they are up
24772 +                * take the first running host */
24773 +               for (k = last_used_backend->value + 1; (int)(k % backends->used) != last_used_backend->value; k++) {
24774 +                       data_proxy *cur = (data_proxy *)backends->data[k % backends->used];
24775 +
24776 +                       if (cur->is_disabled) continue;
24777 +
24778 +                       host = cur;
24779 +
24780 +                       last_used_backend->value = k;
24781 +
24782 +                       break;
24783                 }
24784  
24785 +               if (NULL == host) {
24786 +                       /* we found nothing better, fallback to the last used backend
24787 +                        * and check if it is still up */
24788 +                       host = (data_proxy *)backends->data[last_used_backend->value];
24789 +
24790 +                       if (host->is_disabled) host = NULL;
24791 +               }
24792 +
24793                 break;
24794         default:
24795                 break;
24796         }
24797 -       
24798 -       /* found a server */
24799 -       if (ndx != -1) {
24800 -               data_proxy *host = (data_proxy *)extension->value->data[ndx];
24801 -               
24802 -               /* 
24803 -                * if check-local is disabled, use the uri.path handler 
24804 -                * 
24805 -                */
24806 -               
24807 -               /* init handler-context */
24808 -               handler_ctx *hctx;
24809 -               hctx = handler_ctx_init();
24810 -                               
24811 -               hctx->path_info_offset = path_info_offset;
24812 -               hctx->remote_conn      = con;
24813 -               hctx->plugin_data      = p;
24814 -               hctx->host             = host;
24815 -                               
24816 -               con->plugin_ctx[p->id] = hctx;
24817 -               
24818 -               host->usage++;
24819 -               
24820 -               con->mode = p->id;
24821 -               
24822 -               if (p->conf.debug) {
24823 -                       log_error_write(srv, __FILE__, __LINE__,  "sbd", 
24824 -                                       "proxy - found a host",
24825 -                                       host->host, host->port);
24826 -               }
24827  
24828 -               return HANDLER_GO_ON;
24829 -       } else {
24830 -               /* no handler found */
24831 +       /* we havn't found a host */
24832 +       if (NULL == host) {
24833                 con->http_status = 500;
24834 -               
24835 -               log_error_write(srv, __FILE__, __LINE__,  "sb", 
24836 -                               "no proxy-handler found for:", 
24837 +
24838 +               log_error_write(srv, __FILE__, __LINE__,  "sb",
24839 +                               "no proxy-handler found for:",
24840                                 fn);
24841 -               
24842 +
24843                 return HANDLER_FINISHED;
24844         }
24845 +
24846 +       /* init handler-context */
24847 +       hctx = handler_ctx_init();
24848 +
24849 +       hctx->path_info_offset = path_info_offset;
24850 +       hctx->remote_conn      = con;
24851 +       hctx->plugin_data      = p;
24852 +       hctx->host             = host;
24853 +
24854 +       con->plugin_ctx[p->id] = hctx;
24855 +
24856 +       host->usage++;
24857 +
24858 +       /* we handle this request */
24859 +       con->mode = p->id;
24860 +
24861 +       if (p->conf.debug) {
24862 +               log_error_write(srv, __FILE__, __LINE__,  "sbd",
24863 +                               "proxy - found a host",
24864 +                               host->host, host->port);
24865 +       }
24866 +
24867         return HANDLER_GO_ON;
24868  }
24869  
24870  static handler_t mod_proxy_connection_close_callback(server *srv, connection *con, void *p_d) {
24871         plugin_data *p = p_d;
24872 -       
24873 +
24874         proxy_connection_close(srv, con->plugin_ctx[p->id]);
24875  
24876         return HANDLER_GO_ON;
24877 @@ -1276,11 +1245,11 @@
24878                 size_t i, n, k;
24879                 for (i = 0; i < srv->config_context->used; i++) {
24880                         plugin_config *s = p->config_storage[i];
24881 -                       
24882 -                       if (!s) continue; 
24883  
24884 +                       if (!s) continue;
24885 +
24886                         /* get the extensions for all configs */
24887 -                       
24888 +
24889                         for (k = 0; k < s->extensions->used; k++) {
24890                                 data_array *extension = (data_array *)s->extensions->data[k];
24891  
24892 @@ -1290,8 +1259,8 @@
24893  
24894                                         if (!host->is_disabled ||
24895                                             srv->cur_ts - host->disable_ts < 5) continue;
24896 -                       
24897 -                                       log_error_write(srv, __FILE__, __LINE__,  "sbd", 
24898 +
24899 +                                       log_error_write(srv, __FILE__, __LINE__,  "sbd",
24900                                                         "proxy - re-enabled:",
24901                                                         host->host, host->port);
24902  
24903 @@ -1317,8 +1286,8 @@
24904         p->handle_uri_clean        = mod_proxy_check_extension;
24905         p->handle_subrequest       = mod_proxy_handle_subrequest;
24906         p->handle_trigger          = mod_proxy_trigger;
24907 -       
24908 +
24909         p->data         = NULL;
24910 -       
24911 +
24912         return 0;
24913  }
24914
24915 Property changes on: src/mod_proxy.c
24916 ___________________________________________________________________
24917 Name: svn:eol-style
24918    + native
24919
24920 Index: src/Makefile.am
24921 ===================================================================
24922 --- src/Makefile.am     (.../tags/lighttpd-1.4.11)      (revision 1159)
24923 +++ src/Makefile.am     (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
24924 @@ -16,14 +16,19 @@
24925  else
24926  configparser.y: lemon
24927  mod_ssi_exprparser.y: lemon
24928 +http_resp_parser.y: lemon
24929  
24930  configparser.c configparser.h: configparser.y
24931         rm -f configparser.h
24932 -       $(LEMON) -q $(srcdir)/configparser.y $(srcdir)/lempar.c
24933 +       $(LEMON) -q $(srcdir)/$< $(srcdir)/lempar.c
24934  
24935 +http_resp_parser.c http_resp_parser.h: http_resp_parser.y
24936 +       rm -f http_resp_parser.h
24937 +       $(LEMON) -q $(srcdir)/$< $(srcdir)/lempar.c
24938 +
24939  mod_ssi_exprparser.c mod_ssi_exprparser.h: mod_ssi_exprparser.y 
24940         rm -f mod_ssi_exprparser.h
24941 -       $(LEMON) -q $(srcdir)/mod_ssi_exprparser.y $(srcdir)/lempar.c
24942 +       $(LEMON) -q $(srcdir)/$< $(srcdir)/lempar.c
24943  endif
24944  
24945  configfile.c: configparser.h
24946 @@ -46,7 +51,7 @@
24947        network_write.c network_linux_sendfile.c \
24948        network_freebsd_sendfile.c network_writev.c \
24949        network_solaris_sendfilev.c network_openssl.c \
24950 -      splaytree.c 
24951 +      splaytree.c http_resp.c http_resp_parser.c 
24952        
24953  src = server.c response.c connections.c network.c \
24954        configfile.c configparser.c request.c proc_open.c
24955 @@ -82,9 +87,9 @@
24956  
24957  lib_LTLIBRARIES += mod_webdav.la
24958  mod_webdav_la_SOURCES = mod_webdav.c
24959 -mod_webdav_la_CFLAGS = $(AM_CFLAGS) $(XML_CFLAGS) $(SQLITE_CFLAGS)
24960 +mod_webdav_la_CFLAGS = $(AM_CFLAGS) $(XML_CFLAGS) $(SQLITE_CFLAGS) 
24961  mod_webdav_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
24962 -mod_webdav_la_LIBADD = $(common_libadd) $(XML_LIBS) $(SQLITE_LIBS)
24963 +mod_webdav_la_LIBADD = $(common_libadd) $(XML_LIBS) $(SQLITE_LIBS) $(UUID_LIB)
24964  
24965  lib_LTLIBRARIES += mod_cml.la
24966  mod_cml_la_SOURCES = mod_cml.c mod_cml_lua.c mod_cml_funcs.c
24967 @@ -103,6 +108,11 @@
24968  mod_mysql_vhost_la_LIBADD = $(MYSQL_LIBS) $(common_libadd)
24969  mod_mysql_vhost_la_CPPFLAGS = $(MYSQL_INCLUDE)
24970  
24971 +lib_LTLIBRARIES += mod_sql_vhost_core.la
24972 +mod_sql_vhost_core_la_SOURCES = mod_sql_vhost_core.c
24973 +mod_sql_vhost_core_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
24974 +mod_sql_vhost_core_la_LIBADD = $(common_libadd)
24975 +
24976  lib_LTLIBRARIES += mod_cgi.la
24977  mod_cgi_la_SOURCES = mod_cgi.c 
24978  mod_cgi_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined
24979 @@ -240,7 +250,7 @@
24980        mod_ssi.h mod_ssi_expr.h inet_ntop_cache.h \
24981        configparser.h mod_ssi_exprparser.h \
24982        sys-mmap.h sys-socket.h mod_cml.h mod_cml_funcs.h \
24983 -      splaytree.h proc_open.h
24984 +      splaytree.h proc_open.h http_resp.h mod_sql_vhost_core.h
24985  
24986  DEFS= @DEFS@ -DLIBRARY_DIR="\"$(libdir)\""
24987  
24988
24989 Property changes on: src/Makefile.am
24990 ___________________________________________________________________
24991 Name: svn:eol-style
24992    + native
24993
24994 Index: src/network_writev.c
24995 ===================================================================
24996 --- src/network_writev.c        (.../tags/lighttpd-1.4.11)      (revision 1159)
24997 +++ src/network_writev.c        (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
24998 @@ -28,10 +28,10 @@
24999  
25000  #ifndef UIO_MAXIOV
25001  # if defined(__FreeBSD__) || defined(__APPLE__) || defined(__NetBSD__)
25002 -/* FreeBSD 4.7 defines it in sys/uio.h only if _KERNEL is specified */ 
25003 +/* FreeBSD 4.7 defines it in sys/uio.h only if _KERNEL is specified */
25004  #  define UIO_MAXIOV 1024
25005  # elif defined(__sgi)
25006 -/* IRIX 6.5 has sysconf(_SC_IOV_MAX) which might return 512 or bigger */ 
25007 +/* IRIX 6.5 has sysconf(_SC_IOV_MAX) which might return 512 or bigger */
25008  #  define UIO_MAXIOV 512
25009  # elif defined(__sun)
25010  /* Solaris (and SunOS?) defines IOV_MAX instead */
25011 @@ -51,105 +51,119 @@
25012  #define LOCAL_BUFFERING 1
25013  #endif
25014  
25015 -int network_write_chunkqueue_writev(server *srv, connection *con, int fd, chunkqueue *cq) {
25016 -       chunk *c;
25017 +NETWORK_BACKEND_WRITE_CHUNK(writev_mem) {
25018 +       char * offset;
25019 +       size_t toSend;
25020 +       ssize_t r;
25021 +
25022 +       size_t num_chunks, i;
25023 +       struct iovec chunks[UIO_MAXIOV];
25024 +       chunk *tc; /* transfer chunks */
25025 +       size_t num_bytes = 0;
25026 +
25027 +       /* we can't send more then SSIZE_MAX bytes in one chunk */
25028 +
25029 +       /* build writev list
25030 +        *
25031 +        * 1. limit: num_chunks < UIO_MAXIOV
25032 +        * 2. limit: num_bytes < SSIZE_MAX
25033 +        */
25034 +       for(num_chunks = 0, tc = c; tc && tc->type == MEM_CHUNK && num_chunks < UIO_MAXIOV; num_chunks++, tc = tc->next);
25035 +
25036 +       for(tc = c, i = 0; i < num_chunks; tc = tc->next, i++) {
25037 +               if (tc->mem->used == 0) {
25038 +                       chunks[i].iov_base = tc->mem->ptr;
25039 +                       chunks[i].iov_len  = 0;
25040 +               } else {
25041 +                       offset = tc->mem->ptr + tc->offset;
25042 +                       toSend = tc->mem->used - 1 - tc->offset;
25043 +
25044 +                       chunks[i].iov_base = offset;
25045 +
25046 +                       /* protect the return value of writev() */
25047 +                       if (toSend > SSIZE_MAX ||
25048 +                           num_bytes + toSend > SSIZE_MAX) {
25049 +                               chunks[i].iov_len = SSIZE_MAX - num_bytes;
25050 +
25051 +                               num_chunks = i + 1;
25052 +                               break;
25053 +                       } else {
25054 +                               chunks[i].iov_len = toSend;
25055 +                       }
25056 +
25057 +                       num_bytes += toSend;
25058 +               }
25059 +       }
25060 +
25061 +       if ((r = writev(fd, chunks, num_chunks)) < 0) {
25062 +               switch (errno) {
25063 +               case EAGAIN:
25064 +               case EINTR:
25065 +                       r = 0;
25066 +                       break;
25067 +               case EPIPE:
25068 +               case ECONNRESET:
25069 +                       return NETWORK_STATUS_CONNECTION_CLOSE;
25070 +               default:
25071 +                       log_error_write(srv, __FILE__, __LINE__, "ssd",
25072 +                                       "writev failed:", strerror(errno), fd);
25073 +
25074 +                       return NETWORK_STATUS_FATAL_ERROR;
25075 +               }
25076 +       }
25077 +
25078 +       cq->bytes_out += r;
25079 +
25080 +       /* check which chunks have been written */
25081 +
25082 +       for(i = 0, tc = c; i < num_chunks; i++, tc = tc->next) {
25083 +               if (r >= (ssize_t)chunks[i].iov_len) {
25084 +                       /* written */
25085 +                       r -= chunks[i].iov_len;
25086 +                       tc->offset += chunks[i].iov_len;
25087 +               } else {
25088 +                       /* partially written */
25089 +
25090 +                       tc->offset += r;
25091 +                       break;
25092 +               }
25093 +       }
25094 +
25095 +       return NETWORK_STATUS_SUCCESS;
25096 +}
25097 +
25098 +NETWORK_BACKEND_WRITE(writev) {
25099 +       chunk *c, *tc;
25100         size_t chunks_written = 0;
25101 -       
25102 +
25103         for(c = cq->first; c; c = c->next) {
25104                 int chunk_finished = 0;
25105 -               
25106 +               network_status_t ret;
25107 +
25108                 switch(c->type) {
25109 -               case MEM_CHUNK: {
25110 -                       char * offset;
25111 -                       size_t toSend;
25112 -                       ssize_t r;
25113 -                       
25114 -                       size_t num_chunks, i;
25115 -                       struct iovec chunks[UIO_MAXIOV];
25116 -                       chunk *tc;
25117 -                       size_t num_bytes = 0;
25118 -                       
25119 -                       /* we can't send more then SSIZE_MAX bytes in one chunk */
25120 -                       
25121 -                       /* build writev list 
25122 -                        * 
25123 -                        * 1. limit: num_chunks < UIO_MAXIOV
25124 -                        * 2. limit: num_bytes < SSIZE_MAX
25125 -                        */
25126 -                       for(num_chunks = 0, tc = c; tc && tc->type == MEM_CHUNK && num_chunks < UIO_MAXIOV; num_chunks++, tc = tc->next);
25127 -                       
25128 -                       for(tc = c, i = 0; i < num_chunks; tc = tc->next, i++) {
25129 -                               if (tc->mem->used == 0) {
25130 -                                       chunks[i].iov_base = tc->mem->ptr;
25131 -                                       chunks[i].iov_len  = 0;
25132 -                               } else {
25133 -                                       offset = tc->mem->ptr + tc->offset;
25134 -                                       toSend = tc->mem->used - 1 - tc->offset;
25135 -                               
25136 -                                       chunks[i].iov_base = offset;
25137 -                                       
25138 -                                       /* protect the return value of writev() */
25139 -                                       if (toSend > SSIZE_MAX ||
25140 -                                           num_bytes + toSend > SSIZE_MAX) {
25141 -                                               chunks[i].iov_len = SSIZE_MAX - num_bytes;
25142 -                                               
25143 -                                               num_chunks = i + 1;
25144 -                                               break;
25145 -                                       } else {
25146 -                                               chunks[i].iov_len = toSend;
25147 -                                       }
25148 -                                       
25149 -                                       num_bytes += toSend;
25150 -                               }
25151 -                       }
25152 -                       
25153 -                       if ((r = writev(fd, chunks, num_chunks)) < 0) {
25154 -                               switch (errno) {
25155 -                               case EAGAIN:
25156 -                               case EINTR:
25157 -                                       r = 0;
25158 -                                       break;
25159 -                               case EPIPE:
25160 -                               case ECONNRESET:
25161 -                                       return -2;
25162 -                               default:
25163 -                                       log_error_write(srv, __FILE__, __LINE__, "ssd", 
25164 -                                                       "writev failed:", strerror(errno), fd);
25165 -                               
25166 -                                       return -1;
25167 -                               }
25168 -                       }
25169 -                       
25170 -                       cq->bytes_out += r;
25171 +               case MEM_CHUNK:
25172 +                       ret = network_write_chunkqueue_writev_mem(srv, con, fd, cq, c);
25173  
25174 -                       /* check which chunks have been written */
25175 -                       
25176 -                       for(i = 0, tc = c; i < num_chunks; i++, tc = tc->next) {
25177 -                               if (r >= (ssize_t)chunks[i].iov_len) {
25178 -                                       /* written */
25179 -                                       r -= chunks[i].iov_len;
25180 -                                       tc->offset += chunks[i].iov_len;
25181 -                                       
25182 +                       /* check which chunks are finished now */
25183 +                       for (tc = c; tc; tc = tc->next) {
25184 +                               /* finished the chunk */
25185 +                               if (tc->offset == tc->mem->used - 1) {
25186 +                                       /* skip the first c->next as that will be done by the c = c->next in the other for()-loop */
25187                                         if (chunk_finished) {
25188 -                                               /* skip the chunks from further touches */
25189 -                                               chunks_written++;
25190                                                 c = c->next;
25191                                         } else {
25192 -                                               /* chunks_written + c = c->next is done in the for()*/
25193 -                                               chunk_finished++;
25194 +                                               chunk_finished = 1;
25195                                         }
25196                                 } else {
25197 -                                       /* partially written */
25198 -                                       
25199 -                                       tc->offset += r;
25200 -                                       chunk_finished = 0;
25201 -
25202                                         break;
25203                                 }
25204                         }
25205 -                       
25206 +
25207 +                       if (ret != NETWORK_STATUS_SUCCESS) {
25208 +                               return ret;
25209 +                       }
25210 +
25211                         break;
25212 -               }
25213                 case FILE_CHUNK: {
25214                         ssize_t r;
25215                         off_t abs_offset;
25216 @@ -159,26 +173,26 @@
25217  #define KByte * 1024
25218  #define MByte * 1024 KByte
25219  #define GByte * 1024 MByte
25220 -                       const off_t we_want_to_mmap = 512 KByte; 
25221 +                       const off_t we_want_to_mmap = 512 KByte;
25222                         char *start = NULL;
25223  
25224                         if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) {
25225                                 log_error_write(srv, __FILE__, __LINE__, "sb",
25226                                                 strerror(errno), c->file.name);
25227 -                               return -1;
25228 +                               return NETWORK_STATUS_FATAL_ERROR;
25229                         }
25230  
25231                         abs_offset = c->file.start + c->offset;
25232 -                       
25233 +
25234                         if (abs_offset > sce->st.st_size) {
25235 -                               log_error_write(srv, __FILE__, __LINE__, "sb", 
25236 +                               log_error_write(srv, __FILE__, __LINE__, "sb",
25237                                                 "file was shrinked:", c->file.name);
25238 -                               
25239 -                               return -1;
25240 +
25241 +                               return NETWORK_STATUS_FATAL_ERROR;
25242                         }
25243  
25244 -                       /* mmap the buffer 
25245 -                        * - first mmap 
25246 +                       /* mmap the buffer
25247 +                        * - first mmap
25248                          * - new mmap as the we are at the end of the last one */
25249                         if (c->file.mmap.start == MAP_FAILED ||
25250                             abs_offset == (off_t)(c->file.mmap.offset + c->file.mmap.length)) {
25251 @@ -188,7 +202,7 @@
25252                                  * adaptive mem-mapping
25253                                  *   the problem:
25254                                  *     we mmap() the whole file. If someone has alot large files and 32bit
25255 -                                *     machine the virtual address area will be unrun and we will have a failing 
25256 +                                *     machine the virtual address area will be unrun and we will have a failing
25257                                  *     mmap() call.
25258                                  *   solution:
25259                                  *     only mmap 16M in one chunk and move the window as soon as we have finished
25260 @@ -234,8 +248,8 @@
25261                                 if (-1 == c->file.fd) {  /* open the file if not already open */
25262                                         if (-1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) {
25263                                                 log_error_write(srv, __FILE__, __LINE__, "sbs", "open failed for:", c->file.name, strerror(errno));
25264 -                               
25265 -                                               return -1;
25266 +
25267 +                                               return NETWORK_STATUS_FATAL_ERROR;
25268                                         }
25269  #ifdef FD_CLOEXEC
25270                                         fcntl(c->file.fd, F_SETFD, FD_CLOEXEC);
25271 @@ -245,10 +259,10 @@
25272                                 if (MAP_FAILED == (c->file.mmap.start = mmap(0, to_mmap, PROT_READ, MAP_SHARED, c->file.fd, c->file.mmap.offset))) {
25273                                         /* close it here, otherwise we'd have to set FD_CLOEXEC */
25274  
25275 -                                       log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed:", 
25276 +                                       log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed:",
25277                                                         strerror(errno), c->file.name, c->file.fd);
25278  
25279 -                                       return -1;
25280 +                                       return NETWORK_STATUS_FATAL_ERROR;
25281                                 }
25282  
25283                                 c->file.mmap.length = to_mmap;
25284 @@ -258,7 +272,7 @@
25285  #ifdef HAVE_MADVISE
25286                                 /* don't advise files < 64Kb */
25287                                 if (c->file.mmap.length > (64 KByte)) {
25288 -                                       /* darwin 7 is returning EINVAL all the time and I don't know how to 
25289 +                                       /* darwin 7 is returning EINVAL all the time and I don't know how to
25290                                          * detect this at runtime.i
25291                                          *
25292                                          * ignore the return value for now */
25293 @@ -274,12 +288,12 @@
25294                         toSend = (c->file.mmap.offset + c->file.mmap.length) - (abs_offset);
25295  
25296                         if (toSend < 0) {
25297 -                               log_error_write(srv, __FILE__, __LINE__, "soooo", 
25298 +                               log_error_write(srv, __FILE__, __LINE__, "soooo",
25299                                                 "toSend is negative:",
25300                                                 toSend,
25301                                                 c->file.mmap.length,
25302                                                 abs_offset,
25303 -                                               c->file.mmap.offset); 
25304 +                                               c->file.mmap.offset);
25305                                 assert(toSend < 0);
25306                         }
25307  
25308 @@ -297,18 +311,18 @@
25309                                         break;
25310                                 case EPIPE:
25311                                 case ECONNRESET:
25312 -                                       return -2;
25313 +                                       return NETWORK_STATUS_CONNECTION_CLOSE;
25314                                 default:
25315 -                                       log_error_write(srv, __FILE__, __LINE__, "ssd", 
25316 +                                       log_error_write(srv, __FILE__, __LINE__, "ssd",
25317                                                         "write failed:", strerror(errno), fd);
25318 -                                       
25319 -                                       return -1;
25320 +
25321 +                                       return NETWORK_STATUS_FATAL_ERROR;
25322                                 }
25323                         }
25324 -                       
25325 +
25326                         c->offset += r;
25327                         cq->bytes_out += r;
25328 -                       
25329 +
25330                         if (c->offset == c->file.length) {
25331                                 chunk_finished = 1;
25332  
25333 @@ -318,26 +332,26 @@
25334                                         c->file.mmap.start = MAP_FAILED;
25335                                 }
25336                         }
25337 -                       
25338 +
25339                         break;
25340                 }
25341                 default:
25342 -                       
25343 +
25344                         log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
25345 -                       
25346 -                       return -1;
25347 +
25348 +                       return NETWORK_STATUS_FATAL_ERROR;
25349                 }
25350 -               
25351 +
25352                 if (!chunk_finished) {
25353                         /* not finished yet */
25354 -                       
25355 +
25356                         break;
25357                 }
25358 -               
25359 +
25360                 chunks_written++;
25361         }
25362  
25363 -       return chunks_written;
25364 +       return NETWORK_STATUS_SUCCESS;
25365  }
25366  
25367  #endif
25368
25369 Property changes on: src/network_writev.c
25370 ___________________________________________________________________
25371 Name: svn:eol-style
25372    + native
25373
25374 Index: src/mod_expire.c
25375 ===================================================================
25376 --- src/mod_expire.c    (.../tags/lighttpd-1.4.11)      (revision 1159)
25377 +++ src/mod_expire.c    (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
25378 @@ -12,8 +12,8 @@
25379  #include "stat_cache.h"
25380  
25381  /**
25382 - * this is a expire module for a lighttpd 
25383 - * 
25384 + * this is a expire module for a lighttpd
25385 + *
25386   * set 'Expires:' HTTP Headers on demand
25387   */
25388  
25389 @@ -27,51 +27,51 @@
25390  
25391  typedef struct {
25392         PLUGIN_DATA;
25393 -       
25394 +
25395         buffer *expire_tstmp;
25396 -       
25397 +
25398         plugin_config **config_storage;
25399 -       
25400 -       plugin_config conf; 
25401 +
25402 +       plugin_config conf;
25403  } plugin_data;
25404  
25405  /* init the plugin data */
25406  INIT_FUNC(mod_expire_init) {
25407         plugin_data *p;
25408 -       
25409 +
25410         p = calloc(1, sizeof(*p));
25411 -       
25412 +
25413         p->expire_tstmp = buffer_init();
25414 -       
25415 +
25416         buffer_prepare_copy(p->expire_tstmp, 255);
25417 -       
25418 +
25419         return p;
25420  }
25421  
25422  /* detroy the plugin data */
25423  FREE_FUNC(mod_expire_free) {
25424         plugin_data *p = p_d;
25425 -       
25426 +
25427         UNUSED(srv);
25428  
25429         if (!p) return HANDLER_GO_ON;
25430 -       
25431 +
25432         buffer_free(p->expire_tstmp);
25433 -       
25434 +
25435         if (p->config_storage) {
25436                 size_t i;
25437                 for (i = 0; i < srv->config_context->used; i++) {
25438                         plugin_config *s = p->config_storage[i];
25439 -                       
25440 +
25441                         array_free(s->expire_url);
25442 -                       
25443 +
25444                         free(s);
25445                 }
25446                 free(p->config_storage);
25447         }
25448 -       
25449 +
25450         free(p);
25451 -       
25452 +
25453         return HANDLER_GO_ON;
25454  }
25455  
25456 @@ -79,25 +79,25 @@
25457         char *ts;
25458         int type = -1;
25459         int retts = 0;
25460 -               
25461 +
25462         UNUSED(p);
25463  
25464 -       /* 
25465 +       /*
25466          * parse
25467 -        * 
25468 +        *
25469          * '(access|modification) [plus] {<num> <type>}*'
25470 -        * 
25471 +        *
25472          * e.g. 'access 1 years'
25473          */
25474 -       
25475 +
25476         if (expire->used == 0) {
25477 -               log_error_write(srv, __FILE__, __LINE__, "s", 
25478 +               log_error_write(srv, __FILE__, __LINE__, "s",
25479                                 "empty:");
25480                 return -1;
25481         }
25482 -       
25483 +
25484         ts = expire->ptr;
25485 -       
25486 +
25487         if (0 == strncmp(ts, "access ", 7)) {
25488                 type  = 0;
25489                 ts   += 7;
25490 @@ -110,39 +110,39 @@
25491                                 "invalid <base>:", ts);
25492                 return -1;
25493         }
25494 -       
25495 +
25496         if (0 == strncmp(ts, "plus ", 5)) {
25497                 /* skip the optional plus */
25498                 ts   += 5;
25499         }
25500 -       
25501 +
25502         /* the rest is just <number> (years|months|days|hours|minutes|seconds) */
25503         while (1) {
25504                 char *space, *err;
25505                 int num;
25506 -               
25507 +
25508                 if (NULL == (space = strchr(ts, ' '))) {
25509 -                       log_error_write(srv, __FILE__, __LINE__, "ss", 
25510 +                       log_error_write(srv, __FILE__, __LINE__, "ss",
25511                                         "missing space after <num>:", ts);
25512                         return -1;
25513                 }
25514 -               
25515 +
25516                 num = strtol(ts, &err, 10);
25517                 if (*err != ' ') {
25518 -                       log_error_write(srv, __FILE__, __LINE__, "ss", 
25519 +                       log_error_write(srv, __FILE__, __LINE__, "ss",
25520                                         "missing <type> after <num>:", ts);
25521                         return -1;
25522                 }
25523 -               
25524 +
25525                 ts = space + 1;
25526 -               
25527 +
25528                 if (NULL != (space = strchr(ts, ' '))) {
25529                         int slen;
25530                         /* */
25531 -                       
25532 +
25533                         slen = space - ts;
25534 -                       
25535 -                       if (slen == 5 && 
25536 +
25537 +                       if (slen == 5 &&
25538                             0 == strncmp(ts, "years", slen)) {
25539                                 num *= 60 * 60 * 24 * 30 * 12;
25540                         } else if (slen == 6 &&
25541 @@ -161,13 +161,13 @@
25542                                    0 == strncmp(ts, "seconds", slen)) {
25543                                 num *= 1;
25544                         } else {
25545 -                               log_error_write(srv, __FILE__, __LINE__, "ss", 
25546 +                               log_error_write(srv, __FILE__, __LINE__, "ss",
25547                                                 "unknown type:", ts);
25548                                 return -1;
25549                         }
25550 -                       
25551 +
25552                         retts += num;
25553 -                       
25554 +
25555                         ts = space + 1;
25556                 } else {
25557                         if (0 == strcmp(ts, "years")) {
25558 @@ -183,19 +183,19 @@
25559                         } else if (0 == strcmp(ts, "seconds")) {
25560                                 num *= 1;
25561                         } else {
25562 -                               log_error_write(srv, __FILE__, __LINE__, "ss", 
25563 +                               log_error_write(srv, __FILE__, __LINE__, "ss",
25564                                                 "unknown type:", ts);
25565                                 return -1;
25566                         }
25567 -                       
25568 +
25569                         retts += num;
25570 -                       
25571 +
25572                         break;
25573                 }
25574         }
25575 -       
25576 +
25577         if (offset != NULL) *offset = retts;
25578 -       
25579 +
25580         return type;
25581  }
25582  
25583 @@ -205,102 +205,99 @@
25584  SETDEFAULTS_FUNC(mod_expire_set_defaults) {
25585         plugin_data *p = p_d;
25586         size_t i = 0, k;
25587 -       
25588 -       config_values_t cv[] = { 
25589 +
25590 +       config_values_t cv[] = {
25591                 { "expire.url",                 NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
25592                 { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
25593         };
25594 -       
25595 +
25596         if (!p) return HANDLER_ERROR;
25597 -       
25598 +
25599         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
25600 -       
25601 +
25602         for (i = 0; i < srv->config_context->used; i++) {
25603                 plugin_config *s;
25604 -               
25605 +
25606                 s = calloc(1, sizeof(plugin_config));
25607                 s->expire_url    = array_init();
25608 -               
25609 +
25610                 cv[0].destination = s->expire_url;
25611 -               
25612 +
25613                 p->config_storage[i] = s;
25614 -       
25615 +
25616                 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
25617                         return HANDLER_ERROR;
25618                 }
25619 -       
25620 +
25621                 for (k = 0; k < s->expire_url->used; k++) {
25622                         data_string *ds = (data_string *)s->expire_url->data[k];
25623 -                       
25624 +
25625                         /* parse lines */
25626                         if (-1 == mod_expire_get_offset(srv, p, ds->value, NULL)) {
25627 -                               log_error_write(srv, __FILE__, __LINE__, "sb", 
25628 +                               log_error_write(srv, __FILE__, __LINE__, "sb",
25629                                                 "parsing expire.url failed:", ds->value);
25630                                 return HANDLER_ERROR;
25631                         }
25632                 }
25633         }
25634 -       
25635 -       
25636 +
25637 +
25638         return HANDLER_GO_ON;
25639  }
25640  
25641 -#define PATCH(x) \
25642 -       p->conf.x = s->x;
25643  static int mod_expire_patch_connection(server *srv, connection *con, plugin_data *p) {
25644         size_t i, j;
25645         plugin_config *s = p->config_storage[0];
25646 -       
25647 -       PATCH(expire_url);
25648 -       
25649 +
25650 +       PATCH_OPTION(expire_url);
25651 +
25652         /* skip the first, the global context */
25653         for (i = 1; i < srv->config_context->used; i++) {
25654                 data_config *dc = (data_config *)srv->config_context->data[i];
25655                 s = p->config_storage[i];
25656 -               
25657 +
25658                 /* condition didn't match */
25659                 if (!config_check_cond(srv, con, dc)) continue;
25660 -               
25661 +
25662                 /* merge config */
25663                 for (j = 0; j < dc->value->used; j++) {
25664                         data_unset *du = dc->value->data[j];
25665 -                       
25666 +
25667                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("expire.url"))) {
25668 -                               PATCH(expire_url);
25669 +                               PATCH_OPTION(expire_url);
25670                         }
25671                 }
25672         }
25673 -       
25674 +
25675         return 0;
25676  }
25677 -#undef PATCH
25678  
25679  URIHANDLER_FUNC(mod_expire_path_handler) {
25680         plugin_data *p = p_d;
25681         int s_len;
25682         size_t k;
25683 -       
25684 +
25685         if (con->uri.path->used == 0) return HANDLER_GO_ON;
25686 -       
25687 +
25688         mod_expire_patch_connection(srv, con, p);
25689 -       
25690 +
25691         s_len = con->uri.path->used - 1;
25692 -       
25693 +
25694         for (k = 0; k < p->conf.expire_url->used; k++) {
25695                 data_string *ds = (data_string *)p->conf.expire_url->data[k];
25696                 int ct_len = ds->key->used - 1;
25697 -               
25698 +
25699                 if (ct_len > s_len) continue;
25700                 if (ds->key->used == 0) continue;
25701 -               
25702 +
25703                 if (0 == strncmp(con->uri.path->ptr, ds->key->ptr, ct_len)) {
25704                         int ts;
25705                         time_t t;
25706                         size_t len;
25707                         stat_cache_entry *sce = NULL;
25708 -               
25709 +
25710                         stat_cache_get_entry(srv, con, con->physical.path, &sce);
25711 -                       
25712 +
25713                         switch(mod_expire_get_offset(srv, p, ds->value, &ts)) {
25714                         case 0:
25715                                 /* access */
25716 @@ -308,38 +305,38 @@
25717                                 break;
25718                         case 1:
25719                                 /* modification */
25720 -                               
25721 +
25722                                 t = (ts + sce->st.st_mtime);
25723                                 break;
25724                         default:
25725                                 /* -1 is handled at parse-time */
25726                                 break;
25727                         }
25728 -                       
25729 -                       
25730 -                       if (0 == (len = strftime(p->expire_tstmp->ptr, p->expire_tstmp->size - 1, 
25731 +
25732 +
25733 +                       if (0 == (len = strftime(p->expire_tstmp->ptr, p->expire_tstmp->size - 1,
25734                                            "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(t))))) {
25735                                 /* could not set expire header, out of mem */
25736 -                               
25737 +
25738                                 return HANDLER_GO_ON;
25739 -                               
25740 +
25741                         }
25742 -                           
25743 +
25744                         p->expire_tstmp->used = len + 1;
25745 -               
25746 -                       /* HTTP/1.0 */  
25747 +
25748 +                       /* HTTP/1.0 */
25749                         response_header_overwrite(srv, con, CONST_STR_LEN("Expires"), CONST_BUF_LEN(p->expire_tstmp));
25750  
25751 -                       /* HTTP/1.1 */  
25752 +                       /* HTTP/1.1 */
25753                         buffer_copy_string(p->expire_tstmp, "max-age=");
25754                         buffer_append_long(p->expire_tstmp, ts);
25755 -                       
25756 +
25757                         response_header_overwrite(srv, con, CONST_STR_LEN("Cache-Control"), CONST_BUF_LEN(p->expire_tstmp));
25758 -                       
25759 +
25760                         return HANDLER_GO_ON;
25761                 }
25762         }
25763 -       
25764 +
25765         /* not found */
25766         return HANDLER_GO_ON;
25767  }
25768 @@ -349,13 +346,13 @@
25769  int mod_expire_plugin_init(plugin *p) {
25770         p->version     = LIGHTTPD_VERSION_ID;
25771         p->name        = buffer_init_string("expire");
25772 -       
25773 +
25774         p->init        = mod_expire_init;
25775         p->handle_subrequest_start = mod_expire_path_handler;
25776         p->set_defaults  = mod_expire_set_defaults;
25777         p->cleanup     = mod_expire_free;
25778 -       
25779 +
25780         p->data        = NULL;
25781 -       
25782 +
25783         return 0;
25784  }
25785
25786 Property changes on: src/mod_expire.c
25787 ___________________________________________________________________
25788 Name: svn:eol-style
25789    + native
25790
25791 Index: src/network_openssl.c
25792 ===================================================================
25793 --- src/network_openssl.c       (.../tags/lighttpd-1.4.11)      (revision 1159)
25794 +++ src/network_openssl.c       (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
25795 @@ -23,17 +23,87 @@
25796  #include "log.h"
25797  #include "stat_cache.h"
25798  
25799 -# include <openssl/ssl.h> 
25800 -# include <openssl/err.h> 
25801 +# include <openssl/ssl.h>
25802 +# include <openssl/err.h>
25803  
25804 -int network_write_chunkqueue_openssl(server *srv, connection *con, SSL *ssl, chunkqueue *cq) {
25805 +NETWORK_BACKEND_READ_SSL(openssl) {
25806 +       buffer *b;
25807 +       off_t len;
25808 +
25809 +       b = chunkqueue_get_append_buffer(cq);
25810 +       buffer_prepare_copy(b, 8192);
25811 +       len = SSL_read(ssl, b->ptr, b->size - 1);
25812 +
25813 +       log_error_write(srv, __FILE__, __LINE__, "so", "SSL:", len);
25814 +
25815 +       if (len < 0) {
25816 +               int r, ssl_err;
25817 +
25818 +               switch ((r = SSL_get_error(con->ssl, len))) {
25819 +               case SSL_ERROR_WANT_READ:
25820 +                       return NETWORK_STATUS_WAIT_FOR_EVENT;
25821 +               case SSL_ERROR_SYSCALL:
25822 +                       /**
25823 +                        * man SSL_get_error()
25824 +                        *
25825 +                        * SSL_ERROR_SYSCALL
25826 +                        *   Some I/O error occurred.  The OpenSSL error queue may contain more
25827 +                        *   information on the error.  If the error queue is empty (i.e.
25828 +                        *   ERR_get_error() returns 0), ret can be used to find out more about
25829 +                        *   the error: If ret == 0, an EOF was observed that violates the
25830 +                        *   protocol.  If ret == -1, the underlying BIO reported an I/O error
25831 +                        *   (for socket I/O on Unix systems, consult errno for details).
25832 +                        *
25833 +                        */
25834 +                       while((ssl_err = ERR_get_error())) {
25835 +                               /* get all errors from the error-queue */
25836 +                               log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:",
25837 +                                               r, ERR_error_string(ssl_err, NULL));
25838 +                       }
25839 +
25840 +                       switch(errno) {
25841 +                       default:
25842 +                               log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:",
25843 +                                               len, r, errno,
25844 +                                               strerror(errno));
25845 +                               break;
25846 +                       }
25847 +
25848 +                       break;
25849 +               case SSL_ERROR_ZERO_RETURN:
25850 +                       /* clean shutdown on the remote side */
25851 +
25852 +                       if (r == 0) {
25853 +                               /* FIXME: later */
25854 +                       }
25855 +
25856 +                       /* fall thourgh */
25857 +               default:
25858 +                       while((ssl_err = ERR_get_error())) {
25859 +                               /* get all errors from the error-queue */
25860 +                               log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:",
25861 +                                               r, ERR_error_string(ssl_err, NULL));
25862 +                       }
25863 +                       break;
25864 +               }
25865 +       }
25866 +
25867 +       assert(len > 0);
25868 +       b->used += len;
25869 +       b->ptr[b->used - 1] = '\0';
25870 +
25871 +       return NETWORK_STATUS_SUCCESS;
25872 +}
25873 +
25874 +
25875 +NETWORK_BACKEND_WRITE_SSL(openssl) {
25876         int ssl_r;
25877         chunk *c;
25878         size_t chunks_written = 0;
25879  
25880         /* this is a 64k sendbuffer
25881          *
25882 -        * it has to stay at the same location all the time to satisfy the needs 
25883 +        * it has to stay at the same location all the time to satisfy the needs
25884          * of SSL_write to pass the SAME parameter in case of a _WANT_WRITE
25885          *
25886          * the buffer is allocated once, is NOT realloced and is NOT freed at shutdown
25887 @@ -43,14 +113,14 @@
25888          * In reality we would like to use mmap() but we don't have a guarantee that
25889          * we get the same mmap() address for each call. On openbsd the mmap() address
25890          * even randomized.
25891 -        *   That means either we keep the mmap() open or we do a read() into a 
25892 -        * constant buffer 
25893 +        *   That means either we keep the mmap() open or we do a read() into a
25894 +        * constant buffer
25895          * */
25896  #define LOCAL_SEND_BUFSIZE (64 * 1024)
25897         static char *local_send_buffer = NULL;
25898  
25899         /* the remote side closed the connection before without shutdown request
25900 -        * - IE 
25901 +        * - IE
25902          * - wget
25903          * if keep-alive is disabled */
25904  
25905 @@ -60,32 +130,34 @@
25906  
25907         for(c = cq->first; c; c = c->next) {
25908                 int chunk_finished = 0;
25909 -               
25910 +
25911                 switch(c->type) {
25912                 case MEM_CHUNK: {
25913                         char * offset;
25914                         size_t toSend;
25915 -                       ssize_t r;
25916 -                       
25917 +                       ssize_t r = 0;
25918 +
25919                         if (c->mem->used == 0) {
25920                                 chunk_finished = 1;
25921                                 break;
25922                         }
25923 -                       
25924 +
25925                         offset = c->mem->ptr + c->offset;
25926                         toSend = c->mem->used - 1 - c->offset;
25927 -                       
25928 +
25929                         /**
25930                          * SSL_write man-page
25931 -                        * 
25932 +                        *
25933                          * WARNING
25934                          *        When an SSL_write() operation has to be repeated because of
25935                          *        SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, it must be
25936                          *        repeated with the same arguments.
25937 -                        * 
25938 +                        *
25939 +                        * SSL_write(..., 0) return 0 which is handle as an error (Success)
25940 +                        * checking toSend and not calling SSL_write() is simpler
25941                          */
25942 -                       
25943 -                       if ((r = SSL_write(ssl, offset, toSend)) <= 0) {
25944 +
25945 +                       if (toSend != 0 && (r = SSL_write(ssl, offset, toSend)) <= 0) {
25946                                 unsigned long err;
25947  
25948                                 switch ((ssl_r = SSL_get_error(ssl, r))) {
25949 @@ -95,7 +167,7 @@
25950                                         /* perhaps we have error waiting in our error-queue */
25951                                         if (0 != (err = ERR_get_error())) {
25952                                                 do {
25953 -                                                       log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:", 
25954 +                                                       log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:",
25955                                                                         ssl_r, r,
25956                                                                         ERR_error_string(err, NULL));
25957                                                 } while((err = ERR_get_error()));
25958 @@ -105,43 +177,43 @@
25959                                                 case EPIPE:
25960                                                         return -2;
25961                                                 default:
25962 -                                                       log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:", 
25963 +                                                       log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:",
25964                                                                         ssl_r, r, errno,
25965                                                                         strerror(errno));
25966                                                         break;
25967                                                 }
25968                                         } else {
25969                                                 /* neither error-queue nor errno ? */
25970 -                                               log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL (error):", 
25971 +                                               log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL (error):",
25972                                                                 ssl_r, r, errno,
25973                                                                 strerror(errno));
25974                                         }
25975 -                                       
25976 +
25977                                         return  -1;
25978                                 case SSL_ERROR_ZERO_RETURN:
25979                                         /* clean shutdown on the remote side */
25980 -                                       
25981 +
25982                                         if (r == 0) return -2;
25983 -                                       
25984 +
25985                                         /* fall through */
25986                                 default:
25987                                         while((err = ERR_get_error())) {
25988 -                                               log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:", 
25989 +                                               log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:",
25990                                                                 ssl_r, r,
25991                                                                 ERR_error_string(err, NULL));
25992                                         }
25993 -                                       
25994 +
25995                                         return  -1;
25996                                 }
25997                         } else {
25998                                 c->offset += r;
25999                                 cq->bytes_out += r;
26000                         }
26001 -                       
26002 +
26003                         if (c->offset == (off_t)c->mem->used - 1) {
26004                                 chunk_finished = 1;
26005                         }
26006 -                       
26007 +
26008                         break;
26009                 }
26010                 case FILE_CHUNK: {
26011 @@ -150,7 +222,7 @@
26012                         stat_cache_entry *sce = NULL;
26013                         int ifd;
26014                         int write_wait = 0;
26015 -                       
26016 +
26017                         if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) {
26018                                 log_error_write(srv, __FILE__, __LINE__, "sb",
26019                                                 strerror(errno), c->file.name);
26020 @@ -164,13 +236,13 @@
26021  
26022                         do {
26023                                 off_t offset = c->file.start + c->offset;
26024 -                               off_t toSend = c->file.length - c->offset; 
26025 +                               off_t toSend = c->file.length - c->offset;
26026  
26027                                 if (toSend > LOCAL_SEND_BUFSIZE) toSend = LOCAL_SEND_BUFSIZE;
26028 -                       
26029 +
26030                                 if (-1 == (ifd = open(c->file.name->ptr, O_RDONLY))) {
26031                                         log_error_write(srv, __FILE__, __LINE__, "ss", "open failed:", strerror(errno));
26032 -                               
26033 +
26034                                         return -1;
26035                                 }
26036  
26037 @@ -183,9 +255,9 @@
26038                                 }
26039  
26040                                 s = local_send_buffer;
26041 -                       
26042 +
26043                                 close(ifd);
26044 -                       
26045 +
26046                                 if ((r = SSL_write(ssl, s, toSend)) <= 0) {
26047                                         unsigned long err;
26048  
26049 @@ -197,7 +269,7 @@
26050                                                 /* perhaps we have error waiting in our error-queue */
26051                                                 if (0 != (err = ERR_get_error())) {
26052                                                         do {
26053 -                                                               log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:", 
26054 +                                                               log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:",
26055                                                                                 ssl_r, r,
26056                                                                                 ERR_error_string(err, NULL));
26057                                                         } while((err = ERR_get_error()));
26058 @@ -207,58 +279,58 @@
26059                                                         case EPIPE:
26060                                                                 return -2;
26061                                                         default:
26062 -                                                               log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:", 
26063 +                                                               log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:",
26064                                                                                 ssl_r, r, errno,
26065                                                                                 strerror(errno));
26066                                                                 break;
26067                                                         }
26068                                                 } else {
26069                                                         /* neither error-queue nor errno ? */
26070 -                                                       log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL (error):", 
26071 +                                                       log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL (error):",
26072                                                                         ssl_r, r, errno,
26073                                                                         strerror(errno));
26074                                                 }
26075 -                                       
26076 +
26077                                                 return  -1;
26078                                         case SSL_ERROR_ZERO_RETURN:
26079                                                 /* clean shutdown on the remote side */
26080 -                                       
26081 +
26082                                                 if (r == 0)  return -2;
26083 -                                       
26084 +
26085                                                 /* fall thourgh */
26086                                         default:
26087                                                 while((err = ERR_get_error())) {
26088 -                                                       log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:", 
26089 +                                                       log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:",
26090                                                                         ssl_r, r,
26091                                                                         ERR_error_string(err, NULL));
26092                                                 }
26093 -                                       
26094 +
26095                                                 return -1;
26096                                         }
26097                                 } else {
26098                                         c->offset += r;
26099                                         cq->bytes_out += r;
26100                                 }
26101 -                       
26102 +
26103                                 if (c->offset == c->file.length) {
26104                                         chunk_finished = 1;
26105                                 }
26106                         } while(!chunk_finished && !write_wait);
26107 -                       
26108 +
26109                         break;
26110                 }
26111                 default:
26112                         log_error_write(srv, __FILE__, __LINE__, "s", "type not known");
26113 -                       
26114 +
26115                         return -1;
26116                 }
26117 -                       
26118 +
26119                 if (!chunk_finished) {
26120                         /* not finished yet */
26121 -                       
26122 +
26123                         break;
26124                 }
26125 -                       
26126 +
26127                 chunks_written++;
26128         }
26129  
26130
26131 Property changes on: src/network_openssl.c
26132 ___________________________________________________________________
26133 Name: svn:eol-style
26134    + native
26135
26136 Index: src/network_freebsd_sendfile.c
26137 ===================================================================
26138 --- src/network_freebsd_sendfile.c      (.../tags/lighttpd-1.4.11)      (revision 1159)
26139 +++ src/network_freebsd_sendfile.c      (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
26140 @@ -26,142 +26,61 @@
26141  
26142  #ifndef UIO_MAXIOV
26143  # ifdef __FreeBSD__
26144 -/* FreeBSD 4.7, 4.9 defined it in sys/uio.h only if _KERNEL is specified */ 
26145 +/* FreeBSD 4.7, 4.9 defined it in sys/uio.h only if _KERNEL is specified */
26146  #  define UIO_MAXIOV 1024
26147  # endif
26148  #endif
26149  
26150 -int network_write_chunkqueue_freebsdsendfile(server *srv, connection *con, int fd, chunkqueue *cq) {
26151 +NETWORK_BACKEND_WRITE(freebsdsendfile) {
26152         chunk *c;
26153         size_t chunks_written = 0;
26154 -       
26155 +
26156         for(c = cq->first; c; c = c->next, chunks_written++) {
26157                 int chunk_finished = 0;
26158 -               
26159 +               network_status_t ret;
26160 +
26161                 switch(c->type) {
26162 -               case MEM_CHUNK: {
26163 -                       char * offset;
26164 -                       size_t toSend;
26165 -                       ssize_t r;
26166 -                       
26167 -                       size_t num_chunks, i;
26168 -                       struct iovec chunks[UIO_MAXIOV];
26169 -                       chunk *tc;
26170 -                       size_t num_bytes = 0;
26171 -                       
26172 -                       /* we can't send more then SSIZE_MAX bytes in one chunk */
26173 -                       
26174 -                       /* build writev list 
26175 -                        * 
26176 -                        * 1. limit: num_chunks < UIO_MAXIOV
26177 -                        * 2. limit: num_bytes < SSIZE_MAX
26178 -                        */
26179 -                       for(num_chunks = 0, tc = c; tc && tc->type == MEM_CHUNK && num_chunks < UIO_MAXIOV; num_chunks++, tc = tc->next);
26180 -                       
26181 -                       for(tc = c, i = 0; i < num_chunks; tc = tc->next, i++) {
26182 -                               if (tc->mem->used == 0) {
26183 -                                       chunks[i].iov_base = tc->mem->ptr;
26184 -                                       chunks[i].iov_len  = 0;
26185 -                               } else {
26186 -                                       offset = tc->mem->ptr + tc->offset;
26187 -                                       toSend = tc->mem->used - 1 - tc->offset;
26188 -                                       
26189 -                                       chunks[i].iov_base = offset;
26190 -                                       
26191 -                                       /* protect the return value of writev() */
26192 -                                       if (toSend > SSIZE_MAX ||
26193 -                                           num_bytes + toSend > SSIZE_MAX) {
26194 -                                               chunks[i].iov_len = SSIZE_MAX - num_bytes;
26195 -                                               
26196 -                                               num_chunks = i + 1;
26197 -                                               break;
26198 -                                       } else {
26199 -                                               chunks[i].iov_len = toSend;
26200 -                                       }
26201 -                                
26202 -                                       num_bytes += toSend;
26203 -                               }
26204 -                       }
26205 -                       
26206 -                       if ((r = writev(fd, chunks, num_chunks)) < 0) {
26207 -                               switch (errno) {
26208 -                               case EAGAIN:
26209 -                               case EINTR:
26210 -                                       r = 0;
26211 -                                       break;
26212 -                               case EPIPE:
26213 -                               case ECONNRESET:
26214 -                                       return -2;
26215 -                               default:
26216 -                                       log_error_write(srv, __FILE__, __LINE__, "ssd", 
26217 -                                                       "writev failed:", strerror(errno), fd);
26218 -                                       
26219 -                                       return -1;
26220 -                               }
26221 +               case MEM_CHUNK:
26222 +                       ret = network_write_chunkqueue_writev_mem(srv, con, fd, cq, &c);
26223  
26224 -                               r = 0;
26225 +                       if (ret != NETWORK_STATUS_SUCCESS) {
26226 +                               return ret;
26227                         }
26228 -                       
26229 -                       /* check which chunks have been written */
26230 -                       cq->bytes_out += r;
26231 -                       
26232 -                       for(i = 0, tc = c; i < num_chunks; i++, tc = tc->next) {
26233 -                               if (r >= (ssize_t)chunks[i].iov_len) {
26234 -                                       /* written */
26235 -                                       r -= chunks[i].iov_len;
26236 -                                       tc->offset += chunks[i].iov_len;
26237 -                                       
26238 -                                       if (chunk_finished) {
26239 -                                               /* skip the chunks from further touches */
26240 -                                               chunks_written++;
26241 -                                               c = c->next;
26242 -                                       } else {
26243 -                                               /* chunks_written + c = c->next is done in the for()*/
26244 -                                               chunk_finished++;
26245 -                                       }
26246 -                               } else {
26247 -                                       /* partially written */
26248 -                                       
26249 -                                       tc->offset += r;
26250 -                                       chunk_finished = 0;
26251 -                                       
26252 -                                       break;
26253 -                               }
26254 -                       }
26255 -                       
26256 +
26257 +                       chunk_finished = 1;
26258 +
26259                         break;
26260 -               }
26261                 case FILE_CHUNK: {
26262                         off_t offset, r;
26263                         size_t toSend;
26264                         stat_cache_entry *sce = NULL;
26265                         int ifd;
26266 -                       
26267 +
26268                         if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) {
26269                                 log_error_write(srv, __FILE__, __LINE__, "sb",
26270                                                 strerror(errno), c->file.name);
26271 -                               return -1;
26272 +                               return NETWORK_STATUS_FATAL_ERROR;
26273                         }
26274 -                       
26275 +
26276                         offset = c->file.start + c->offset;
26277                         /* limit the toSend to 2^31-1 bytes in a chunk */
26278 -                       toSend = c->file.length - c->offset > ((1 << 30) - 1) ? 
26279 +                       toSend = c->file.length - c->offset > ((1 << 30) - 1) ?
26280                                 ((1 << 30) - 1) : c->file.length - c->offset;
26281 -                               
26282 +
26283                         if (offset > sce->st.st_size) {
26284                                 log_error_write(srv, __FILE__, __LINE__, "sb", "file was shrinked:", c->file.name);
26285 -                               
26286 -                               return -1;
26287 +
26288 +                               return NETWORK_STATUS_FATAL_ERROR;
26289                         }
26290 -                       
26291 +
26292                         if (-1 == (ifd = open(c->file.name->ptr, O_RDONLY))) {
26293                                 log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
26294 -                               
26295 -                               return -1;
26296 +
26297 +                               return NETWORK_STATUS_FATAL_ERROR;
26298                         }
26299 -                       
26300 +
26301                         r = 0;
26302 -                       
26303 +
26304                         /* FreeBSD sendfile() */
26305                         if (-1 == sendfile(ifd, fd, offset, toSend, NULL, &r, 0)) {
26306                                 switch(errno) {
26307 @@ -169,39 +88,39 @@
26308                                         break;
26309                                 case ENOTCONN:
26310                                         close(ifd);
26311 -                                       return -2;
26312 +                                       return NETWORK_STATUS_CONNECTION_CLOSE;
26313                                 default:
26314                                         log_error_write(srv, __FILE__, __LINE__, "ssd", "sendfile: ", strerror(errno), errno);
26315                                         close(ifd);
26316 -                                       return -1;
26317 +                                       return NETWORK_STATUS_FATAL_ERROR;
26318                                 }
26319                         }
26320                         close(ifd);
26321 -                       
26322 +
26323                         c->offset += r;
26324                         cq->bytes_out += r;
26325 -                       
26326 +
26327                         if (c->offset == c->file.length) {
26328                                 chunk_finished = 1;
26329                         }
26330 -                       
26331 +
26332                         break;
26333                 }
26334                 default:
26335 -                       
26336 +
26337                         log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
26338 -                       
26339 +
26340                         return -1;
26341                 }
26342 -               
26343 +
26344                 if (!chunk_finished) {
26345                         /* not finished yet */
26346 -                       
26347 +
26348                         break;
26349                 }
26350         }
26351  
26352 -       return chunks_written;
26353 +       return NETWORK_STATUS_SUCCESS;
26354  }
26355  
26356  #endif
26357
26358 Property changes on: src/network_freebsd_sendfile.c
26359 ___________________________________________________________________
26360 Name: svn:eol-style
26361    + native
26362
26363
26364 Property changes on: src/http_auth_digest.c
26365 ___________________________________________________________________
26366 Name: svn:eol-style
26367    + native
26368
26369 Index: src/mod_redirect.c
26370 ===================================================================
26371 --- src/mod_redirect.c  (.../tags/lighttpd-1.4.11)      (revision 1159)
26372 +++ src/mod_redirect.c  (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
26373 @@ -22,35 +22,35 @@
26374         PLUGIN_DATA;
26375         buffer *match_buf;
26376         buffer *location;
26377 -       
26378 +
26379         plugin_config **config_storage;
26380 -       
26381 -       plugin_config conf; 
26382 +
26383 +       plugin_config conf;
26384  } plugin_data;
26385  
26386  INIT_FUNC(mod_redirect_init) {
26387         plugin_data *p;
26388 -       
26389 +
26390         p = calloc(1, sizeof(*p));
26391 -       
26392 +
26393         p->match_buf = buffer_init();
26394         p->location = buffer_init();
26395 -       
26396 +
26397         return p;
26398  }
26399  
26400  FREE_FUNC(mod_redirect_free) {
26401         plugin_data *p = p_d;
26402 -       
26403 +
26404         if (!p) return HANDLER_GO_ON;
26405  
26406         if (p->config_storage) {
26407                 size_t i;
26408                 for (i = 0; i < srv->config_context->used; i++) {
26409                         plugin_config *s = p->config_storage[i];
26410 -                       
26411 +
26412                         pcre_keyvalue_buffer_free(s->redirect);
26413 -                       
26414 +
26415                         free(s);
26416                 }
26417                 free(p->config_storage);
26418 @@ -59,9 +59,9 @@
26419  
26420         buffer_free(p->match_buf);
26421         buffer_free(p->location);
26422 -       
26423 +
26424         free(p);
26425 -       
26426 +
26427         return HANDLER_GO_ON;
26428  }
26429  
26430 @@ -69,195 +69,137 @@
26431         plugin_data *p = p_d;
26432         data_unset *du;
26433         size_t i = 0;
26434 -       
26435 -       config_values_t cv[] = { 
26436 +
26437 +       config_values_t cv[] = {
26438                 { "url.redirect",               NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
26439                 { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
26440         };
26441 -       
26442 +
26443         if (!p) return HANDLER_ERROR;
26444 -       
26445 +
26446         /* 0 */
26447         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
26448 -       
26449 +
26450         for (i = 0; i < srv->config_context->used; i++) {
26451                 plugin_config *s;
26452                 size_t j;
26453                 array *ca;
26454                 data_array *da = (data_array *)du;
26455 -               
26456 +
26457                 s = calloc(1, sizeof(plugin_config));
26458                 s->redirect   = pcre_keyvalue_buffer_init();
26459 -               
26460 +
26461                 cv[0].destination = s->redirect;
26462 -               
26463 +
26464                 p->config_storage[i] = s;
26465                 ca = ((data_config *)srv->config_context->data[i])->value;
26466 -       
26467 +
26468                 if (0 != config_insert_values_global(srv, ca, cv)) {
26469                         return HANDLER_ERROR;
26470                 }
26471 -               
26472 +
26473                 if (NULL == (du = array_get_element(ca, "url.redirect"))) {
26474                         /* no url.redirect defined */
26475                         continue;
26476                 }
26477 -               
26478 +
26479                 if (du->type != TYPE_ARRAY) {
26480 -                       log_error_write(srv, __FILE__, __LINE__, "sss", 
26481 +                       log_error_write(srv, __FILE__, __LINE__, "sss",
26482                                         "unexpected type for key: ", "url.redirect", "array of strings");
26483 -                       
26484 +
26485                         return HANDLER_ERROR;
26486                 }
26487 -               
26488 +
26489                 da = (data_array *)du;
26490 -                               
26491 +
26492                 for (j = 0; j < da->value->used; j++) {
26493                         if (da->value->data[j]->type != TYPE_STRING) {
26494 -                               log_error_write(srv, __FILE__, __LINE__, "sssbs", 
26495 -                                               "unexpected type for key: ", 
26496 -                                               "url.redirect", 
26497 +                               log_error_write(srv, __FILE__, __LINE__, "sssbs",
26498 +                                               "unexpected type for key: ",
26499 +                                               "url.redirect",
26500                                                 "[", da->value->data[j]->key, "](string)");
26501 -                               
26502 +
26503                                 return HANDLER_ERROR;
26504                         }
26505 -                               
26506 -                       if (0 != pcre_keyvalue_buffer_append(s->redirect, 
26507 +
26508 +                       if (0 != pcre_keyvalue_buffer_append(s->redirect,
26509                                                              ((data_string *)(da->value->data[j]))->key->ptr,
26510                                                              ((data_string *)(da->value->data[j]))->value->ptr)) {
26511 -                                       
26512 -                               log_error_write(srv, __FILE__, __LINE__, "sb", 
26513 +
26514 +                               log_error_write(srv, __FILE__, __LINE__, "sb",
26515                                                 "pcre-compile failed for", da->value->data[j]->key);
26516                         }
26517                 }
26518         }
26519 -       
26520 +
26521         return HANDLER_GO_ON;
26522  }
26523  #ifdef HAVE_PCRE_H
26524  static int mod_redirect_patch_connection(server *srv, connection *con, plugin_data *p) {
26525         size_t i, j;
26526         plugin_config *s = p->config_storage[0];
26527 -       
26528 +
26529         p->conf.redirect = s->redirect;
26530 -       
26531 +
26532         /* skip the first, the global context */
26533         for (i = 1; i < srv->config_context->used; i++) {
26534                 data_config *dc = (data_config *)srv->config_context->data[i];
26535                 s = p->config_storage[i];
26536 -               
26537 +
26538                 /* condition didn't match */
26539                 if (!config_check_cond(srv, con, dc)) continue;
26540 -               
26541 +
26542                 /* merge config */
26543                 for (j = 0; j < dc->value->used; j++) {
26544                         data_unset *du = dc->value->data[j];
26545 -                       
26546 +
26547                         if (0 == strcmp(du->key->ptr, "url.redirect")) {
26548                                 p->conf.redirect = s->redirect;
26549                                 p->conf.context = dc;
26550                         }
26551                 }
26552         }
26553 -       
26554 +
26555         return 0;
26556  }
26557  #endif
26558  static handler_t mod_redirect_uri_handler(server *srv, connection *con, void *p_data) {
26559  #ifdef HAVE_PCRE_H
26560         plugin_data *p = p_data;
26561 -       size_t i;
26562 +       int i;
26563  
26564 -       /* 
26565 +       /*
26566          * REWRITE URL
26567 -        * 
26568 +        *
26569          * e.g. redirect /base/ to /index.php?section=base
26570 -        * 
26571 +        *
26572          */
26573 -       
26574 +
26575         mod_redirect_patch_connection(srv, con, p);
26576 -       
26577 +
26578         buffer_copy_string_buffer(p->match_buf, con->request.uri);
26579 -       
26580 -       for (i = 0; i < p->conf.redirect->used; i++) {
26581 -               pcre *match;
26582 -               pcre_extra *extra;
26583 -               const char *pattern;
26584 -               size_t pattern_len;
26585 -               int n;
26586 -               pcre_keyvalue *kv = p->conf.redirect->kv[i];
26587 -# define N 10
26588 -               int ovec[N * 3];
26589 -               
26590 -               match       = kv->key;
26591 -               extra       = kv->key_extra;
26592 -               pattern     = kv->value->ptr;
26593 -               pattern_len = kv->value->used - 1;
26594 -               
26595 -               if ((n = pcre_exec(match, extra, p->match_buf->ptr, p->match_buf->used - 1, 0, 0, ovec, 3 * N)) < 0) {
26596 -                       if (n != PCRE_ERROR_NOMATCH) {
26597 -                               log_error_write(srv, __FILE__, __LINE__, "sd",
26598 -                                               "execution error while matching: ", n);
26599 -                               return HANDLER_ERROR;
26600 -                       }
26601 -               } else {
26602 -                       const char **list;
26603 -                       size_t start, end;
26604 -                       size_t k;
26605 -                       
26606 -                       /* it matched */
26607 -                       pcre_get_substring_list(p->match_buf->ptr, ovec, n, &list);
26608 -                       
26609 -                       /* search for $[0-9] */
26610 -                       
26611 -                       buffer_reset(p->location);
26612 -                       
26613 -                       start = 0; end = pattern_len;
26614 -                       for (k = 0; k < pattern_len; k++) {
26615 -                               if ((pattern[k] == '$' || pattern[k] == '%') &&
26616 -                                   isdigit((unsigned char)pattern[k + 1])) {
26617 -                                       /* got one */
26618 -                                       
26619 -                                       size_t num = pattern[k + 1] - '0';
26620 -                                       
26621 -                                       end = k;
26622 -                                       
26623 -                                       buffer_append_string_len(p->location, pattern + start, end - start);
26624 -                                       
26625 -                                       if (pattern[k] == '$') {
26626 -                                               /* n is always > 0 */
26627 -                                               if (num < (size_t)n) {
26628 -                                                       buffer_append_string(p->location, list[num]);
26629 -                                               }
26630 -                                       } else {
26631 -                                               config_append_cond_match_buffer(con, p->conf.context, p->location, num);
26632 -                                       }
26633 -                                       
26634 -                                       k++;
26635 -                                       start = k + 1;
26636 -                               } 
26637 -                       }
26638 -                       
26639 -                       buffer_append_string_len(p->location, pattern + start, pattern_len - start);
26640 -                       
26641 -                       pcre_free(list);
26642 -                       
26643 -                       response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->location));
26644 -                       
26645 -                       con->http_status = 301;
26646 -                       con->file_finished = 1;
26647 -                       
26648 -                       return HANDLER_FINISHED;
26649 -               }
26650 +       i = config_exec_pcre_keyvalue_buffer(con, p->conf.redirect, p->conf.context, p->match_buf, p->location);
26651 +
26652 +       if (i >= 0) {
26653 +               response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->location));
26654 +
26655 +               con->http_status = 301;
26656 +               con->file_finished = 1;
26657 +
26658 +               return HANDLER_FINISHED;
26659         }
26660 +       else if (i != PCRE_ERROR_NOMATCH) {
26661 +               log_error_write(srv, __FILE__, __LINE__, "s",
26662 +                               "execution error while matching", i);
26663 +       }
26664  #undef N
26665 -               
26666 +
26667  #else
26668         UNUSED(srv);
26669         UNUSED(con);
26670         UNUSED(p_data);
26671  #endif
26672 -       
26673 +
26674         return HANDLER_GO_ON;
26675  }
26676  
26677 @@ -265,13 +207,13 @@
26678  int mod_redirect_plugin_init(plugin *p) {
26679         p->version     = LIGHTTPD_VERSION_ID;
26680         p->name        = buffer_init_string("redirect");
26681 -       
26682 +
26683         p->init        = mod_redirect_init;
26684         p->handle_uri_clean  = mod_redirect_uri_handler;
26685         p->set_defaults  = mod_redirect_set_defaults;
26686         p->cleanup     = mod_redirect_free;
26687 -       
26688 +
26689         p->data        = NULL;
26690 -       
26691 +
26692         return 0;
26693  }
26694
26695 Property changes on: src/mod_redirect.c
26696 ___________________________________________________________________
26697 Name: svn:eol-style
26698    + native
26699
26700 Index: src/http_auth.c
26701 ===================================================================
26702 --- src/http_auth.c     (.../tags/lighttpd-1.4.11)      (revision 1159)
26703 +++ src/http_auth.c     (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
26704 @@ -22,7 +22,6 @@
26705  #include <string.h>
26706  #include <time.h>
26707  #include <errno.h>
26708 -#include <unistd.h>
26709  #include <ctype.h>
26710  
26711  #include "server.h"
26712 @@ -31,23 +30,14 @@
26713  #include "http_auth_digest.h"
26714  #include "stream.h"
26715  
26716 +#include "sys-strings.h"
26717 +
26718  #ifdef USE_OPENSSL
26719  # include <openssl/md5.h>
26720  #else
26721  # include "md5.h"
26722  #endif
26723  
26724 -
26725 -#ifdef USE_PAM
26726 -#include <security/pam_appl.h>
26727 -#include <security/pam_misc.h>
26728 -
26729 -static struct pam_conv conv = {
26730 -       misc_conv,
26731 -               NULL
26732 -};
26733 -#endif
26734 -
26735  handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s);
26736  
26737  static const char base64_pad = '=';
26738 @@ -75,25 +65,25 @@
26739         unsigned char *result;
26740         int ch, j = 0, k;
26741         size_t i;
26742 -       
26743 +
26744         size_t in_len = strlen(in);
26745 -       
26746 +
26747         buffer_prepare_copy(out, in_len);
26748 -       
26749 +
26750         result = (unsigned char *)out->ptr;
26751 -       
26752 +
26753         ch = in[0];
26754         /* run through the whole string, converting as we go */
26755         for (i = 0; i < in_len; i++) {
26756                 ch = in[i];
26757 -               
26758 +
26759                 if (ch == '\0') break;
26760 -               
26761 +
26762                 if (ch == base64_pad) break;
26763 -               
26764 +
26765                 ch = base64_reverse_table[ch];
26766                 if (ch < 0) continue;
26767 -               
26768 +
26769                 switch(i % 4) {
26770                 case 0:
26771                         result[j] = ch << 2;
26772 @@ -125,168 +115,168 @@
26773                 }
26774         }
26775         result[k] = '\0';
26776 -       
26777 +
26778         out->used = k;
26779 -       
26780 +
26781         return result;
26782  }
26783  
26784  static int http_auth_get_password(server *srv, mod_auth_plugin_data *p, buffer *username, buffer *realm, buffer *password) {
26785         int ret = -1;
26786 -       
26787 +
26788         if (!username->used|| !realm->used) return -1;
26789 -       
26790 +
26791         if (p->conf.auth_backend == AUTH_BACKEND_HTDIGEST) {
26792                 stream f;
26793                 char * f_line;
26794 -               
26795 +
26796                 if (buffer_is_empty(p->conf.auth_htdigest_userfile)) return -1;
26797 -               
26798 +
26799                 if (0 != stream_open(&f, p->conf.auth_htdigest_userfile)) {
26800                         log_error_write(srv, __FILE__, __LINE__, "sbss", "opening digest-userfile", p->conf.auth_htdigest_userfile, "failed:", strerror(errno));
26801 -                       
26802 +
26803                         return -1;
26804                 }
26805 -               
26806 +
26807                 f_line = f.start;
26808 -               
26809 +
26810                 while (f_line - f.start != f.size) {
26811                         char *f_user, *f_pwd, *e, *f_realm;
26812                         size_t u_len, pwd_len, r_len;
26813 -                       
26814 +
26815                         f_user = f_line;
26816 -                       
26817 -                       /* 
26818 +
26819 +                       /*
26820                          * htdigest format
26821 -                        * 
26822 -                        * user:realm:md5(user:realm:password) 
26823 +                        *
26824 +                        * user:realm:md5(user:realm:password)
26825                          */
26826 -                       
26827 +
26828                         if (NULL == (f_realm = memchr(f_user, ':', f.size - (f_user - f.start) ))) {
26829 -                               log_error_write(srv, __FILE__, __LINE__, "sbs", 
26830 -                                               "parsed error in", p->conf.auth_htdigest_userfile, 
26831 +                               log_error_write(srv, __FILE__, __LINE__, "sbs",
26832 +                                               "parsed error in", p->conf.auth_htdigest_userfile,
26833                                                 "expected 'username:realm:hashed password'");
26834 -                               
26835 +
26836                                 stream_close(&f);
26837 -                               
26838 +
26839                                 return -1;
26840                         }
26841 -                       
26842 +
26843                         if (NULL == (f_pwd = memchr(f_realm + 1, ':', f.size - (f_realm + 1 - f.start)))) {
26844 -                               log_error_write(srv, __FILE__, __LINE__, "sbs", 
26845 -                                               "parsed error in", p->conf.auth_plain_userfile, 
26846 +                               log_error_write(srv, __FILE__, __LINE__, "sbs",
26847 +                                               "parsed error in", p->conf.auth_plain_userfile,
26848                                                 "expected 'username:realm:hashed password'");
26849 -                               
26850 +
26851                                 stream_close(&f);
26852 -                               
26853 +
26854                                 return -1;
26855                         }
26856 -                       
26857 +
26858                         /* get pointers to the fields */
26859 -                       u_len = f_realm - f_user; 
26860 +                       u_len = f_realm - f_user;
26861                         f_realm++;
26862                         r_len = f_pwd - f_realm;
26863                         f_pwd++;
26864 -                       
26865 +
26866                         if (NULL != (e = memchr(f_pwd, '\n', f.size - (f_pwd - f.start)))) {
26867                                 pwd_len = e - f_pwd;
26868                         } else {
26869                                 pwd_len = f.size - (f_pwd - f.start);
26870                         }
26871 -                       
26872 +
26873                         if (username->used - 1 == u_len &&
26874                             (realm->used - 1 == r_len) &&
26875                             (0 == strncmp(username->ptr, f_user, u_len)) &&
26876                             (0 == strncmp(realm->ptr, f_realm, r_len))) {
26877                                 /* found */
26878 -                               
26879 +
26880                                 buffer_copy_string_len(password, f_pwd, pwd_len);
26881 -                               
26882 +
26883                                 ret = 0;
26884                                 break;
26885                         }
26886 -                       
26887 +
26888                         /* EOL */
26889                         if (!e) break;
26890 -                       
26891 +
26892                         f_line = e + 1;
26893                 }
26894 -               
26895 +
26896                 stream_close(&f);
26897         } else if (p->conf.auth_backend == AUTH_BACKEND_HTPASSWD ||
26898                    p->conf.auth_backend == AUTH_BACKEND_PLAIN) {
26899                 stream f;
26900                 char * f_line;
26901                 buffer *auth_fn;
26902 -               
26903 +
26904                 auth_fn = (p->conf.auth_backend == AUTH_BACKEND_HTPASSWD) ? p->conf.auth_htpasswd_userfile : p->conf.auth_plain_userfile;
26905 -               
26906 +
26907                 if (buffer_is_empty(auth_fn)) return -1;
26908 -               
26909 +
26910                 if (0 != stream_open(&f, auth_fn)) {
26911 -                       log_error_write(srv, __FILE__, __LINE__, "sbss", 
26912 +                       log_error_write(srv, __FILE__, __LINE__, "sbss",
26913                                         "opening plain-userfile", auth_fn, "failed:", strerror(errno));
26914 -                       
26915 +
26916                         return -1;
26917                 }
26918 -               
26919 +
26920                 f_line = f.start;
26921 -               
26922 +
26923                 while (f_line - f.start != f.size) {
26924                         char *f_user, *f_pwd, *e;
26925                         size_t u_len, pwd_len;
26926 -                       
26927 +
26928                         f_user = f_line;
26929 -                       
26930 -                       /* 
26931 +
26932 +                       /*
26933                          * htpasswd format
26934 -                        * 
26935 +                        *
26936                          * user:crypted passwd
26937                          */
26938 -                       
26939 +
26940                         if (NULL == (f_pwd = memchr(f_user, ':', f.size - (f_user - f.start) ))) {
26941 -                               log_error_write(srv, __FILE__, __LINE__, "sbs", 
26942 -                                               "parsed error in", auth_fn, 
26943 +                               log_error_write(srv, __FILE__, __LINE__, "sbs",
26944 +                                               "parsed error in", auth_fn,
26945                                                 "expected 'username:hashed password'");
26946 -                               
26947 +
26948                                 stream_close(&f);
26949 -                               
26950 +
26951                                 return -1;
26952                         }
26953 -                       
26954 +
26955                         /* get pointers to the fields */
26956 -                       u_len = f_pwd - f_user; 
26957 +                       u_len = f_pwd - f_user;
26958                         f_pwd++;
26959 -                       
26960 +
26961                         if (NULL != (e = memchr(f_pwd, '\n', f.size - (f_pwd - f.start)))) {
26962                                 pwd_len = e - f_pwd;
26963                         } else {
26964                                 pwd_len = f.size - (f_pwd - f.start);
26965                         }
26966 -                       
26967 +
26968                         if (username->used - 1 == u_len &&
26969                             (0 == strncmp(username->ptr, f_user, u_len))) {
26970                                 /* found */
26971 -                               
26972 +
26973                                 buffer_copy_string_len(password, f_pwd, pwd_len);
26974 -                               
26975 +
26976                                 ret = 0;
26977                                 break;
26978                         }
26979 -                       
26980 +
26981                         /* EOL */
26982                         if (!e) break;
26983 -                       
26984 +
26985                         f_line = e + 1;
26986                 }
26987 -               
26988 +
26989                 stream_close(&f);
26990         } else if (p->conf.auth_backend == AUTH_BACKEND_LDAP) {
26991                 ret = 0;
26992         } else {
26993                 return -1;
26994         }
26995 -       
26996 +
26997         return ret;
26998  }
26999  
27000 @@ -296,7 +286,7 @@
27001         int username_len;
27002         data_string *require;
27003         array *req;
27004 -       
27005 +
27006         UNUSED(group);
27007         UNUSED(host);
27008  
27009 @@ -304,12 +294,12 @@
27010         /* search auth-directives for path */
27011         for (i = 0; i < p->conf.auth_require->used; i++) {
27012                 if (p->conf.auth_require->data[i]->key->used == 0) continue;
27013 -               
27014 +
27015                 if (0 == strncmp(url, p->conf.auth_require->data[i]->key->ptr, p->conf.auth_require->data[i]->key->used - 1)) {
27016                         break;
27017                 }
27018         }
27019 -       
27020 +
27021         if (i == p->conf.auth_require->used) {
27022                 return -1;
27023         }
27024 @@ -317,72 +307,72 @@
27025         req = ((data_array *)(p->conf.auth_require->data[i]))->value;
27026  
27027         require = (data_string *)array_get_element(req, "require");
27028 -       
27029 +
27030         /* if we get here, the user we got a authed user */
27031         if (0 == strcmp(require->value->ptr, "valid-user")) {
27032                 return 0;
27033         }
27034 -       
27035 +
27036         /* user=name1|group=name3|host=name4 */
27037 -       
27038 +
27039         /* seperate the string by | */
27040  #if 0
27041         log_error_write(srv, __FILE__, __LINE__, "sb", "rules", require->value);
27042 -#endif 
27043 -       
27044 +#endif
27045 +
27046         username_len = username ? strlen(username) : 0;
27047 -       
27048 +
27049         r = rules = require->value->ptr;
27050 -       
27051 +
27052         while (1) {
27053                 const char *eq;
27054                 const char *k, *v, *e;
27055                 int k_len, v_len, r_len;
27056 -               
27057 +
27058                 e = strchr(r, '|');
27059 -               
27060 +
27061                 if (e) {
27062                         r_len = e - r;
27063                 } else {
27064                         r_len = strlen(rules) - (r - rules);
27065                 }
27066 -               
27067 +
27068                 /* from r to r + r_len is a rule */
27069 -               
27070 +
27071                 if (0 == strncmp(r, "valid-user", r_len)) {
27072 -                       log_error_write(srv, __FILE__, __LINE__, "sb", 
27073 +                       log_error_write(srv, __FILE__, __LINE__, "sb",
27074                                         "parsing the 'require' section in 'auth.require' failed: valid-user cannot be combined with other require rules",
27075                                         require->value);
27076                         return -1;
27077                 }
27078 -               
27079 +
27080                 /* search for = in the rules */
27081                 if (NULL == (eq = strchr(r, '='))) {
27082 -                       log_error_write(srv, __FILE__, __LINE__, "sb", 
27083 -                                       "parsing the 'require' section in 'auth.require' failed: a = is missing", 
27084 +                       log_error_write(srv, __FILE__, __LINE__, "sb",
27085 +                                       "parsing the 'require' section in 'auth.require' failed: a = is missing",
27086                                         require->value);
27087                         return -1;
27088                 }
27089 -               
27090 +
27091                 /* = out of range */
27092                 if (eq > r + r_len) {
27093 -                       log_error_write(srv, __FILE__, __LINE__, "sb", 
27094 +                       log_error_write(srv, __FILE__, __LINE__, "sb",
27095                                         "parsing the 'require' section in 'auth.require' failed: = out of range",
27096                                         require->value);
27097 -                       
27098 +
27099                         return -1;
27100                 }
27101 -               
27102 +
27103                 /* the part before the = is user|group|host */
27104 -               
27105 +
27106                 k = r;
27107                 k_len = eq - r;
27108                 v = eq + 1;
27109                 v_len = r_len - k_len - 1;
27110 -               
27111 +
27112                 if (k_len == 4) {
27113                         if (0 == strncmp(k, "user", k_len)) {
27114 -                               if (username && 
27115 +                               if (username &&
27116                                     username_len == v_len &&
27117                                     0 == strncmp(username, v, v_len)) {
27118                                         return 0;
27119 @@ -404,19 +394,19 @@
27120                         log_error_write(srv, __FILE__, __LINE__, "s", "unknown  key");
27121                         return -1;
27122                 }
27123 -               
27124 +
27125                 if (!e) break;
27126                 r = e + 1;
27127         }
27128 -       
27129 +
27130         log_error_write(srv, __FILE__, __LINE__, "s", "nothing matched");
27131 -       
27132 +
27133         return -1;
27134  }
27135  
27136  /**
27137 - * 
27138 - * 
27139 + *
27140 + *
27141   * @param password password-string from the auth-backend
27142   * @param pw       password-string from the client
27143   */
27144 @@ -426,16 +416,16 @@
27145         UNUSED(req);
27146  
27147         if (p->conf.auth_backend == AUTH_BACKEND_HTDIGEST) {
27148 -               /* 
27149 +               /*
27150                  * htdigest format
27151 -                * 
27152 -                * user:realm:md5(user:realm:password) 
27153 +                *
27154 +                * user:realm:md5(user:realm:password)
27155                  */
27156 -               
27157 +
27158                 MD5_CTX Md5Ctx;
27159                 HASH HA1;
27160                 char a1[256];
27161 -               
27162 +
27163                 MD5_Init(&Md5Ctx);
27164                 MD5_Update(&Md5Ctx, (unsigned char *)username->ptr, username->used - 1);
27165                 MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
27166 @@ -443,24 +433,24 @@
27167                 MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
27168                 MD5_Update(&Md5Ctx, (unsigned char *)pw, strlen(pw));
27169                 MD5_Final(HA1, &Md5Ctx);
27170 -               
27171 +
27172                 CvtHex(HA1, a1);
27173 -               
27174 +
27175                 if (0 == strcmp(password->ptr, a1)) {
27176                         return 0;
27177                 }
27178 -       } else if (p->conf.auth_backend == AUTH_BACKEND_HTPASSWD) { 
27179 -#ifdef HAVE_CRYPT      
27180 +       } else if (p->conf.auth_backend == AUTH_BACKEND_HTPASSWD) {
27181 +#ifdef HAVE_CRYPT
27182                 char salt[32];
27183                 char *crypted;
27184                 size_t salt_len = 0;
27185 -               /* 
27186 +               /*
27187                  * htpasswd format
27188 -                * 
27189 +                *
27190                  * user:crypted password
27191                  */
27192  
27193 -               /* 
27194 +               /*
27195                  *  Algorithm      Salt
27196                  *  CRYPT_STD_DES   2-character (Default)
27197                  *  CRYPT_EXT_DES   9-character
27198 @@ -478,7 +468,7 @@
27199                         salt_len = 2;
27200                 } else if (password->ptr[0] == '$' && password->ptr[2] == '$') {
27201                         char *dollar = NULL;
27202 -               
27203 +
27204                         if (NULL == (dollar = strchr(password->ptr + 3, '$'))) {
27205                                 fprintf(stderr, "%s.%d\n", __FILE__, __LINE__);
27206                                 return -1;
27207 @@ -495,7 +485,7 @@
27208                 strncpy(salt, password->ptr, salt_len);
27209  
27210                 salt[salt_len] = '\0';
27211 -               
27212 +
27213                 crypted = crypt(pw, salt);
27214  
27215                 if (0 == strcmp(password->ptr, crypted)) {
27216 @@ -503,40 +493,13 @@
27217                 } else {
27218                         fprintf(stderr, "%s.%d\n", __FILE__, __LINE__);
27219                 }
27220 -       
27221 -#endif 
27222 -       } else if (p->conf.auth_backend == AUTH_BACKEND_PLAIN) { 
27223 +
27224 +#endif
27225 +       } else if (p->conf.auth_backend == AUTH_BACKEND_PLAIN) {
27226                 if (0 == strcmp(password->ptr, pw)) {
27227                         return 0;
27228                 }
27229 -       } else if (p->conf.auth_backend == AUTH_BACKEND_PAM) { 
27230 -#ifdef USE_PAM
27231 -               pam_handle_t *pamh=NULL;
27232 -               int retval;
27233 -               
27234 -               retval = pam_start("lighttpd", username->ptr, &conv, &pamh);
27235 -               
27236 -               if (retval == PAM_SUCCESS)
27237 -                       retval = pam_authenticate(pamh, 0);    /* is user really user? */
27238 -               
27239 -               if (retval == PAM_SUCCESS)
27240 -                       retval = pam_acct_mgmt(pamh, 0);       /* permitted access? */
27241 -               
27242 -               /* This is where we have been authorized or not. */
27243 -               
27244 -               if (pam_end(pamh,retval) != PAM_SUCCESS) {     /* close Linux-PAM */
27245 -                       pamh = NULL;
27246 -                       log_error_write(srv, __FILE__, __LINE__, "s", "failed to release authenticator");
27247 -               }
27248 -               
27249 -               if (retval == PAM_SUCCESS) {
27250 -                       log_error_write(srv, __FILE__, __LINE__, "s", "Authenticated");
27251 -                       return 0;
27252 -               } else {
27253 -                       log_error_write(srv, __FILE__, __LINE__, "s", "Not Authenticated");
27254 -               }
27255 -#endif
27256 -       } else if (p->conf.auth_backend == AUTH_BACKEND_LDAP) { 
27257 +       } else if (p->conf.auth_backend == AUTH_BACKEND_LDAP) {
27258  #ifdef USE_LDAP
27259                 LDAP *ldap;
27260                 LDAPMessage *lm, *first;
27261 @@ -544,45 +507,45 @@
27262                 int ret;
27263                 char *attrs[] = { LDAP_NO_ATTRS, NULL };
27264                 size_t i;
27265 -               
27266 +
27267                 /* for now we stay synchronous */
27268 -               
27269 -               /* 
27270 +
27271 +               /*
27272                  * 1. connect anonymously (done in plugin init)
27273                  * 2. get DN for uid = username
27274                  * 3. auth against ldap server
27275                  * 4. (optional) check a field
27276                  * 5. disconnect
27277 -                * 
27278 +                *
27279                  */
27280 -               
27281 +
27282                 /* check username
27283 -                * 
27284 +                *
27285                  * we have to protect us againt username which modifies out filter in
27286                  * a unpleasant way
27287                  */
27288 -               
27289 +
27290                 for (i = 0; i < username->used - 1; i++) {
27291                         char c = username->ptr[i];
27292 -                       
27293 +
27294                         if (!isalpha(c) &&
27295                             !isdigit(c)) {
27296 -                               
27297 -                               log_error_write(srv, __FILE__, __LINE__, "sbd", 
27298 +
27299 +                               log_error_write(srv, __FILE__, __LINE__, "sbd",
27300                                         "ldap: invalid character (a-zA-Z0-9 allowed) in username:", username, i);
27301 -                               
27302 +
27303                                 return -1;
27304                         }
27305                 }
27306 -               
27307 -               
27308 -               
27309 +
27310 +
27311 +
27312                 /* build filter */
27313                 buffer_copy_string_buffer(p->ldap_filter, p->conf.ldap_filter_pre);
27314                 buffer_append_string_buffer(p->ldap_filter, username);
27315                 buffer_append_string_buffer(p->ldap_filter, p->conf.ldap_filter_post);
27316 -               
27317 -               
27318 +
27319 +
27320                 /* 2. */
27321                 if (p->conf.ldap == NULL ||
27322                     LDAP_SUCCESS != (ret = ldap_search_s(p->conf.ldap, p->conf.auth_ldap_basedn->ptr, LDAP_SCOPE_SUBTREE, p->ldap_filter->ptr, attrs, 0, &lm))) {
27323 @@ -590,71 +553,71 @@
27324                                 return -1;
27325                         if (LDAP_SUCCESS != (ret = ldap_search_s(p->conf.ldap, p->conf.auth_ldap_basedn->ptr, LDAP_SCOPE_SUBTREE, p->ldap_filter->ptr, attrs, 0, &lm))) {
27326  
27327 -                       log_error_write(srv, __FILE__, __LINE__, "sssb", 
27328 +                       log_error_write(srv, __FILE__, __LINE__, "sssb",
27329                                         "ldap:", ldap_err2string(ret), "filter:", p->ldap_filter);
27330 -                       
27331 +
27332                         return -1;
27333                         }
27334                 }
27335 -               
27336 +
27337                 if (NULL == (first = ldap_first_entry(p->conf.ldap, lm))) {
27338                         log_error_write(srv, __FILE__, __LINE__, "s", "ldap ...");
27339 -                       
27340 +
27341                         ldap_msgfree(lm);
27342 -                       
27343 +
27344                         return -1;
27345                 }
27346 -               
27347 +
27348                 if (NULL == (dn = ldap_get_dn(p->conf.ldap, first))) {
27349                         log_error_write(srv, __FILE__, __LINE__, "s", "ldap ...");
27350 -                       
27351 +
27352                         ldap_msgfree(lm);
27353 -                       
27354 +
27355                         return -1;
27356                 }
27357 -               
27358 +
27359                 ldap_msgfree(lm);
27360 -               
27361 -               
27362 +
27363 +
27364                 /* 3. */
27365                 if (NULL == (ldap = ldap_init(p->conf.auth_ldap_hostname->ptr, LDAP_PORT))) {
27366                         log_error_write(srv, __FILE__, __LINE__, "ss", "ldap ...", strerror(errno));
27367                         return -1;
27368                 }
27369 -               
27370 +
27371                 ret = LDAP_VERSION3;
27372                 if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &ret))) {
27373                         log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
27374 -                       
27375 +
27376                         ldap_unbind_s(ldap);
27377 -                       
27378 +
27379                         return -1;
27380                 }
27381 -               
27382 +
27383                 if (p->conf.auth_ldap_starttls == 1) {
27384                         if (LDAP_OPT_SUCCESS != (ret = ldap_start_tls_s(ldap, NULL,  NULL))) {
27385                                 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap startTLS failed:", ldap_err2string(ret));
27386 -               
27387 +
27388                                 ldap_unbind_s(ldap);
27389 -                               
27390 +
27391                                 return -1;
27392                         }
27393                 }
27394  
27395 -               
27396 +
27397                 if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(ldap, dn, pw))) {
27398                         log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
27399 -                       
27400 +
27401                         ldap_unbind_s(ldap);
27402 -                       
27403 +
27404                         return -1;
27405                 }
27406 -               
27407 +
27408                 /* 5. */
27409                 ldap_unbind_s(ldap);
27410 -               
27411 +
27412                 /* everything worked, good, access granted */
27413 -               
27414 +
27415                 return 0;
27416  #endif
27417         }
27418 @@ -664,65 +627,65 @@
27419  int http_auth_basic_check(server *srv, connection *con, mod_auth_plugin_data *p, array *req, buffer *url, const char *realm_str) {
27420         buffer *username, *password;
27421         char *pw;
27422 -       
27423 +
27424         data_string *realm;
27425 -       
27426 +
27427         realm = (data_string *)array_get_element(req, "realm");
27428 -       
27429 +
27430         username = buffer_init();
27431         password = buffer_init();
27432 -       
27433 +
27434         base64_decode(username, realm_str);
27435 -       
27436 +
27437         /* r2 == user:password */
27438         if (NULL == (pw = strchr(username->ptr, ':'))) {
27439                 buffer_free(username);
27440 -               
27441 +
27442                 log_error_write(srv, __FILE__, __LINE__, "sb", ": is missing in", username);
27443 -               
27444 +
27445                 return 0;
27446         }
27447 -       
27448 +
27449         *pw++ = '\0';
27450 -       
27451 +
27452         username->used = pw - username->ptr;
27453 -       
27454 +
27455         /* copy password to r1 */
27456         if (http_auth_get_password(srv, p, username, realm->value, password)) {
27457                 buffer_free(username);
27458                 buffer_free(password);
27459 -               
27460 +
27461                 log_error_write(srv, __FILE__, __LINE__, "s", "get_password failed");
27462 -               
27463 +
27464                 return 0;
27465         }
27466 -       
27467 +
27468         /* password doesn't match */
27469         if (http_auth_basic_password_compare(srv, p, req, username, realm->value, password, pw)) {
27470                 log_error_write(srv, __FILE__, __LINE__, "sbb", "password doesn't match for", con->uri.path, username);
27471 -               
27472 +
27473                 buffer_free(username);
27474                 buffer_free(password);
27475 -               
27476 +
27477                 return 0;
27478         }
27479 -       
27480 +
27481         /* value is our allow-rules */
27482         if (http_auth_match_rules(srv, p, url->ptr, username->ptr, NULL, NULL)) {
27483                 buffer_free(username);
27484                 buffer_free(password);
27485 -               
27486 +
27487                 log_error_write(srv, __FILE__, __LINE__, "s", "rules didn't match");
27488 -               
27489 +
27490                 return 0;
27491         }
27492 -       
27493 +
27494         /* remember the username */
27495         buffer_copy_string_buffer(p->auth_user, username);
27496 -       
27497 +
27498         buffer_free(username);
27499         buffer_free(password);
27500 -       
27501 +
27502         return 1;
27503  }
27504  
27505 @@ -735,7 +698,7 @@
27506  int http_auth_digest_check(server *srv, connection *con, mod_auth_plugin_data *p, array *req, buffer *url, const char *realm_str) {
27507         char a1[256];
27508         char a2[256];
27509 -       
27510 +
27511         char *username;
27512         char *realm;
27513         char *nonce;
27514 @@ -745,19 +708,19 @@
27515         char *cnonce;
27516         char *nc;
27517         char *respons;
27518 -       
27519 +
27520         char *e, *c;
27521         const char *m = NULL;
27522         int i;
27523         buffer *password, *b, *username_buf, *realm_buf;
27524 -       
27525 +
27526         MD5_CTX Md5Ctx;
27527         HASH HA1;
27528         HASH HA2;
27529         HASH RespHash;
27530         HASHHEX HA2Hex;
27531 -       
27532  
27533 +
27534         /* init pointers */
27535  #define S(x) \
27536         x, sizeof(x)-1, NULL
27537 @@ -771,11 +734,11 @@
27538                 { S("cnonce=") },
27539                 { S("nc=") },
27540                 { S("response=") },
27541 -               
27542 +
27543                 { NULL, 0, NULL }
27544         };
27545  #undef S
27546 -       
27547 +
27548         dkv[0].ptr = &username;
27549         dkv[1].ptr = &realm;
27550         dkv[2].ptr = &nonce;
27551 @@ -786,24 +749,24 @@
27552         dkv[7].ptr = &nc;
27553         dkv[8].ptr = &respons;
27554         dkv[9].ptr = NULL;
27555 -       
27556 +
27557         UNUSED(req);
27558 -       
27559 +
27560         for (i = 0; dkv[i].key; i++) {
27561                 *(dkv[i].ptr) = NULL;
27562         }
27563 -       
27564 -       
27565 +
27566 +
27567         if (p->conf.auth_backend != AUTH_BACKEND_HTDIGEST &&
27568             p->conf.auth_backend != AUTH_BACKEND_PLAIN) {
27569 -               log_error_write(srv, __FILE__, __LINE__, "s", 
27570 +               log_error_write(srv, __FILE__, __LINE__, "s",
27571                                 "digest: unsupported backend (only htdigest or plain)");
27572 -               
27573 +
27574                 return -1;
27575         }
27576 -       
27577 +
27578         b = buffer_init_string(realm_str);
27579 -       
27580 +
27581         /* parse credentials from client */
27582         for (c = b->ptr; *c; c++) {
27583                 /* skip whitespaces */
27584 @@ -812,18 +775,18 @@
27585  
27586                 for (i = 0; dkv[i].key; i++) {
27587                         if ((0 == strncmp(c, dkv[i].key, dkv[i].key_len))) {
27588 -                               if ((c[dkv[i].key_len] == '"') && 
27589 +                               if ((c[dkv[i].key_len] == '"') &&
27590                                     (NULL != (e = strchr(c + dkv[i].key_len + 1, '"')))) {
27591                                         /* value with "..." */
27592                                         *(dkv[i].ptr) = c + dkv[i].key_len + 1;
27593                                         c = e;
27594 -       
27595 +
27596                                         *e = '\0';
27597                                 } else if (NULL != (e = strchr(c + dkv[i].key_len, ','))) {
27598                                         /* value without "...", terminated by ',' */
27599                                         *(dkv[i].ptr) = c + dkv[i].key_len;
27600                                         c = e;
27601 -                                       
27602 +
27603                                         *e = '\0';
27604                                 } else {
27605                                         /* value without "...", terminated by EOL */
27606 @@ -833,7 +796,7 @@
27607                         }
27608                 }
27609         }
27610 -       
27611 +
27612         if (p->conf.auth_debug > 1) {
27613                 log_error_write(srv, __FILE__, __LINE__, "ss", "username", username);
27614                 log_error_write(srv, __FILE__, __LINE__, "ss", "realm", realm);
27615 @@ -845,22 +808,22 @@
27616                 log_error_write(srv, __FILE__, __LINE__, "ss", "nc", nc);
27617                 log_error_write(srv, __FILE__, __LINE__, "ss", "response", respons);
27618         }
27619 -       
27620 +
27621         /* check if everything is transmitted */
27622 -       if (!username || 
27623 +       if (!username ||
27624             !realm ||
27625             !nonce ||
27626             !uri ||
27627             (qop && (!nc || !cnonce)) ||
27628             !respons ) {
27629                 /* missing field */
27630 -               
27631 -               log_error_write(srv, __FILE__, __LINE__, "s", 
27632 +
27633 +               log_error_write(srv, __FILE__, __LINE__, "s",
27634                                 "digest: missing field");
27635                 return -1;
27636         }
27637  
27638 -       m = get_http_method_name(con->request.http_method);     
27639 +       m = get_http_method_name(con->request.http_method);
27640  
27641         /* password-string == HA1 */
27642         password = buffer_init();
27643 @@ -873,10 +836,10 @@
27644                 buffer_free(realm_buf);
27645                 return 0;
27646         }
27647 -       
27648 +
27649         buffer_free(username_buf);
27650         buffer_free(realm_buf);
27651 -       
27652 +
27653         if (p->conf.auth_backend == AUTH_BACKEND_PLAIN) {
27654                 /* generate password from plain-text */
27655                 MD5_Init(&Md5Ctx);
27656 @@ -890,16 +853,16 @@
27657                 /* HA1 */
27658                 /* transform the 32-byte-hex-md5 to a 16-byte-md5 */
27659                 for (i = 0; i < HASHLEN; i++) {
27660 -                       HA1[i] = hex2int(password->ptr[i*2]) << 4; 
27661 -                       HA1[i] |= hex2int(password->ptr[i*2+1]); 
27662 +                       HA1[i] = hex2int(password->ptr[i*2]) << 4;
27663 +                       HA1[i] |= hex2int(password->ptr[i*2+1]);
27664                 }
27665         } else {
27666                 /* we already check that above */
27667                 SEGFAULT();
27668         }
27669 -       
27670 +
27671         buffer_free(password);
27672 -       
27673 +
27674         if (algorithm &&
27675             strcasecmp(algorithm, "md5-sess") == 0) {
27676                 MD5_Init(&Md5Ctx);
27677 @@ -910,9 +873,9 @@
27678                 MD5_Update(&Md5Ctx, (unsigned char *)cnonce, strlen(cnonce));
27679                 MD5_Final(HA1, &Md5Ctx);
27680         }
27681 -       
27682 +
27683         CvtHex(HA1, a1);
27684 -       
27685 +
27686         /* calculate H(A2) */
27687         MD5_Init(&Md5Ctx);
27688         MD5_Update(&Md5Ctx, (unsigned char *)m, strlen(m));
27689 @@ -924,7 +887,7 @@
27690         }
27691         MD5_Final(HA2, &Md5Ctx);
27692         CvtHex(HA2, HA2Hex);
27693 -       
27694 +
27695         /* calculate response */
27696         MD5_Init(&Md5Ctx);
27697         MD5_Update(&Md5Ctx, (unsigned char *)a1, HASHHEXLEN);
27698 @@ -942,39 +905,39 @@
27699         MD5_Update(&Md5Ctx, (unsigned char *)HA2Hex, HASHHEXLEN);
27700         MD5_Final(RespHash, &Md5Ctx);
27701         CvtHex(RespHash, a2);
27702 -       
27703 +
27704         if (0 != strcmp(a2, respons)) {
27705                 /* digest not ok */
27706 -               
27707 +
27708                 if (p->conf.auth_debug) {
27709 -                       log_error_write(srv, __FILE__, __LINE__, "sss", 
27710 +                       log_error_write(srv, __FILE__, __LINE__, "sss",
27711                                 "digest: digest mismatch", a2, respons);
27712                 }
27713 -               
27714 -               log_error_write(srv, __FILE__, __LINE__, "sss", 
27715 +
27716 +               log_error_write(srv, __FILE__, __LINE__, "sss",
27717                                 "digest: auth failed for", username, "wrong password");
27718 -               
27719 +
27720                 buffer_free(b);
27721                 return 0;
27722         }
27723 -       
27724 +
27725         /* value is our allow-rules */
27726         if (http_auth_match_rules(srv, p, url->ptr, username, NULL, NULL)) {
27727                 buffer_free(b);
27728 -               
27729 -               log_error_write(srv, __FILE__, __LINE__, "s", 
27730 +
27731 +               log_error_write(srv, __FILE__, __LINE__, "s",
27732                                 "digest: rules did match");
27733 -               
27734 +
27735                 return 0;
27736         }
27737 -       
27738 +
27739         /* remember the username */
27740         buffer_copy_string(p->auth_user, username);
27741 -       
27742 +
27743         buffer_free(b);
27744 -       
27745 +
27746         if (p->conf.auth_debug) {
27747 -               log_error_write(srv, __FILE__, __LINE__, "s", 
27748 +               log_error_write(srv, __FILE__, __LINE__, "s",
27749                                 "digest: auth ok");
27750         }
27751         return 1;
27752 @@ -985,23 +948,23 @@
27753         HASH h;
27754         MD5_CTX Md5Ctx;
27755         char hh[32];
27756 -       
27757 +
27758         UNUSED(p);
27759  
27760         /* generate shared-secret */
27761         MD5_Init(&Md5Ctx);
27762         MD5_Update(&Md5Ctx, (unsigned char *)fn->ptr, fn->used - 1);
27763         MD5_Update(&Md5Ctx, (unsigned char *)"+", 1);
27764 -       
27765 +
27766         /* we assume sizeof(time_t) == 4 here, but if not it ain't a problem at all */
27767         ltostr(hh, srv->cur_ts);
27768         MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
27769         ltostr(hh, rand());
27770         MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
27771 -       
27772 +
27773         MD5_Final(h, &Md5Ctx);
27774 -       
27775 +
27776         CvtHex(h, out);
27777 -       
27778 +
27779         return 0;
27780  }
27781
27782 Property changes on: src/http_auth.c
27783 ___________________________________________________________________
27784 Name: svn:eol-style
27785    + native
27786
27787 Index: src/mod_usertrack.c
27788 ===================================================================
27789 --- src/mod_usertrack.c (.../tags/lighttpd-1.4.11)      (revision 1159)
27790 +++ src/mod_usertrack.c (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
27791 @@ -24,44 +24,44 @@
27792  
27793  typedef struct {
27794         PLUGIN_DATA;
27795 -       
27796 +
27797         plugin_config **config_storage;
27798 -       
27799 -       plugin_config conf; 
27800 +
27801 +       plugin_config conf;
27802  } plugin_data;
27803  
27804  /* init the plugin data */
27805  INIT_FUNC(mod_usertrack_init) {
27806         plugin_data *p;
27807 -       
27808 +
27809         p = calloc(1, sizeof(*p));
27810 -       
27811 +
27812         return p;
27813  }
27814  
27815  /* detroy the plugin data */
27816  FREE_FUNC(mod_usertrack_free) {
27817         plugin_data *p = p_d;
27818 -       
27819 +
27820         UNUSED(srv);
27821 -       
27822 +
27823         if (!p) return HANDLER_GO_ON;
27824 -       
27825 +
27826         if (p->config_storage) {
27827                 size_t i;
27828                 for (i = 0; i < srv->config_context->used; i++) {
27829                         plugin_config *s = p->config_storage[i];
27830 -                       
27831 +
27832                         buffer_free(s->cookie_name);
27833                         buffer_free(s->cookie_domain);
27834 -                       
27835 +
27836                         free(s);
27837                 }
27838                 free(p->config_storage);
27839         }
27840 -       
27841 +
27842         free(p);
27843 -       
27844 +
27845         return HANDLER_GO_ON;
27846  }
27847  
27848 @@ -70,38 +70,38 @@
27849  SETDEFAULTS_FUNC(mod_usertrack_set_defaults) {
27850         plugin_data *p = p_d;
27851         size_t i = 0;
27852 -       
27853 -       config_values_t cv[] = { 
27854 +
27855 +       config_values_t cv[] = {
27856                 { "usertrack.cookie-name",       NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
27857                 { "usertrack.cookie-max-age",    NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 1 */
27858                 { "usertrack.cookie-domain",     NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 2 */
27859 -               
27860 -               { "usertrack.cookiename",        NULL, T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_CONNECTION },   
27861 +
27862 +               { "usertrack.cookiename",        NULL, T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_CONNECTION },
27863                 { NULL,                          NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
27864         };
27865 -       
27866 +
27867         if (!p) return HANDLER_ERROR;
27868 -       
27869 +
27870         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
27871 -       
27872 +
27873         for (i = 0; i < srv->config_context->used; i++) {
27874                 plugin_config *s;
27875 -               
27876 +
27877                 s = calloc(1, sizeof(plugin_config));
27878                 s->cookie_name    = buffer_init();
27879                 s->cookie_domain  = buffer_init();
27880                 s->cookie_max_age = 0;
27881 -               
27882 +
27883                 cv[0].destination = s->cookie_name;
27884                 cv[1].destination = &(s->cookie_max_age);
27885                 cv[2].destination = s->cookie_domain;
27886 -               
27887 +
27888                 p->config_storage[i] = s;
27889 -       
27890 +
27891                 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
27892                         return HANDLER_ERROR;
27893                 }
27894 -       
27895 +
27896                 if (buffer_is_empty(s->cookie_name)) {
27897                         buffer_copy_string(s->cookie_name, "TRACKID");
27898                 } else {
27899 @@ -109,68 +109,65 @@
27900                         for (j = 0; j < s->cookie_name->used - 1; j++) {
27901                                 char c = s->cookie_name->ptr[j] | 32;
27902                                 if (c < 'a' || c > 'z') {
27903 -                                       log_error_write(srv, __FILE__, __LINE__, "sb", 
27904 -                                                       "invalid character in usertrack.cookie-name:", 
27905 +                                       log_error_write(srv, __FILE__, __LINE__, "sb",
27906 +                                                       "invalid character in usertrack.cookie-name:",
27907                                                         s->cookie_name);
27908 -                                       
27909 +
27910                                         return HANDLER_ERROR;
27911                                 }
27912                         }
27913                 }
27914 -               
27915 +
27916                 if (!buffer_is_empty(s->cookie_domain)) {
27917                         size_t j;
27918                         for (j = 0; j < s->cookie_domain->used - 1; j++) {
27919                                 char c = s->cookie_domain->ptr[j];
27920                                 if (c <= 32 || c >= 127 || c == '"' || c == '\\') {
27921 -                                       log_error_write(srv, __FILE__, __LINE__, "sb", 
27922 -                                                       "invalid character in usertrack.cookie-domain:", 
27923 +                                       log_error_write(srv, __FILE__, __LINE__, "sb",
27924 +                                                       "invalid character in usertrack.cookie-domain:",
27925                                                         s->cookie_domain);
27926 -                                       
27927 +
27928                                         return HANDLER_ERROR;
27929                                 }
27930                         }
27931                 }
27932         }
27933 -               
27934 +
27935         return HANDLER_GO_ON;
27936  }
27937  
27938 -#define PATCH(x) \
27939 -       p->conf.x = s->x;
27940  static int mod_usertrack_patch_connection(server *srv, connection *con, plugin_data *p) {
27941         size_t i, j;
27942         plugin_config *s = p->config_storage[0];
27943 -       
27944 -       PATCH(cookie_name);
27945 -       PATCH(cookie_domain);
27946 -       PATCH(cookie_max_age);
27947 -       
27948 +
27949 +       PATCH_OPTION(cookie_name);
27950 +       PATCH_OPTION(cookie_domain);
27951 +       PATCH_OPTION(cookie_max_age);
27952 +
27953         /* skip the first, the global context */
27954         for (i = 1; i < srv->config_context->used; i++) {
27955                 data_config *dc = (data_config *)srv->config_context->data[i];
27956                 s = p->config_storage[i];
27957 -               
27958 +
27959                 /* condition didn't match */
27960                 if (!config_check_cond(srv, con, dc)) continue;
27961 -               
27962 +
27963                 /* merge config */
27964                 for (j = 0; j < dc->value->used; j++) {
27965                         data_unset *du = dc->value->data[j];
27966 -                       
27967 +
27968                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("usertrack.cookie-name"))) {
27969 -                               PATCH(cookie_name);
27970 +                               PATCH_OPTION(cookie_name);
27971                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("usertrack.cookie-max-age"))) {
27972 -                               PATCH(cookie_max_age);
27973 +                               PATCH_OPTION(cookie_max_age);
27974                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("usertrack.cookie-domain"))) {
27975 -                               PATCH(cookie_domain);
27976 +                               PATCH_OPTION(cookie_domain);
27977                         }
27978                 }
27979         }
27980 -       
27981 +
27982         return 0;
27983  }
27984 -#undef PATCH
27985  
27986  URIHANDLER_FUNC(mod_usertrack_uri_handler) {
27987         plugin_data *p = p_d;
27988 @@ -178,38 +175,38 @@
27989         unsigned char h[16];
27990         MD5_CTX Md5Ctx;
27991         char hh[32];
27992 -       
27993 +
27994         if (con->uri.path->used == 0) return HANDLER_GO_ON;
27995 -       
27996 +
27997         mod_usertrack_patch_connection(srv, con, p);
27998 -       
27999 +
28000         if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Cookie"))) {
28001                 char *g;
28002                 /* we have a cookie, does it contain a valid name ? */
28003 -               
28004 -               /* parse the cookie 
28005 -                * 
28006 +
28007 +               /* parse the cookie
28008 +                *
28009                  * check for cookiename + (WS | '=')
28010 -                * 
28011 +                *
28012                  */
28013 -               
28014 +
28015                 if (NULL != (g = strstr(ds->value->ptr, p->conf.cookie_name->ptr))) {
28016                         char *nc;
28017 -                       
28018 +
28019                         /* skip WS */
28020                         for (nc = g + p->conf.cookie_name->used-1; *nc == ' ' || *nc == '\t'; nc++);
28021 -                       
28022 +
28023                         if (*nc == '=') {
28024                                 /* ok, found the key of our own cookie */
28025 -                               
28026 +
28027                                 if (strlen(nc) > 32) {
28028                                         /* i'm lazy */
28029                                         return HANDLER_GO_ON;
28030                                 }
28031                         }
28032                 }
28033 -       } 
28034 -       
28035 +       }
28036 +
28037         /* set a cookie */
28038         if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
28039                 ds = data_response_init();
28040 @@ -217,39 +214,39 @@
28041         buffer_copy_string(ds->key, "Set-Cookie");
28042         buffer_copy_string_buffer(ds->value, p->conf.cookie_name);
28043         buffer_append_string(ds->value, "=");
28044 -       
28045  
28046 +
28047         /* taken from mod_auth.c */
28048 -       
28049 +
28050         /* generate shared-secret */
28051         MD5_Init(&Md5Ctx);
28052         MD5_Update(&Md5Ctx, (unsigned char *)con->uri.path->ptr, con->uri.path->used - 1);
28053         MD5_Update(&Md5Ctx, (unsigned char *)"+", 1);
28054 -       
28055 +
28056         /* we assume sizeof(time_t) == 4 here, but if not it ain't a problem at all */
28057         ltostr(hh, srv->cur_ts);
28058         MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
28059         ltostr(hh, rand());
28060         MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
28061 -       
28062 +
28063         MD5_Final(h, &Md5Ctx);
28064 -       
28065 +
28066         buffer_append_string_encoded(ds->value, (char *)h, 16, ENCODING_HEX);
28067         buffer_append_string(ds->value, "; Path=/");
28068         buffer_append_string(ds->value, "; Version=1");
28069 -       
28070 +
28071         if (!buffer_is_empty(p->conf.cookie_domain)) {
28072                 buffer_append_string(ds->value, "; Domain=");
28073                 buffer_append_string_encoded(ds->value, CONST_BUF_LEN(p->conf.cookie_domain), ENCODING_REL_URI);
28074         }
28075 -       
28076 +
28077         if (p->conf.cookie_max_age) {
28078                 buffer_append_string(ds->value, "; max-age=");
28079                 buffer_append_long(ds->value, p->conf.cookie_max_age);
28080         }
28081 -       
28082 +
28083         array_insert_unique(con->response.headers, (data_unset *)ds);
28084 -       
28085 +
28086         return HANDLER_GO_ON;
28087  }
28088  
28089 @@ -258,13 +255,13 @@
28090  int mod_usertrack_plugin_init(plugin *p) {
28091         p->version     = LIGHTTPD_VERSION_ID;
28092         p->name        = buffer_init_string("usertrack");
28093 -       
28094 +
28095         p->init        = mod_usertrack_init;
28096         p->handle_uri_clean  = mod_usertrack_uri_handler;
28097         p->set_defaults  = mod_usertrack_set_defaults;
28098         p->cleanup     = mod_usertrack_free;
28099 -       
28100 +
28101         p->data        = NULL;
28102 -       
28103 +
28104         return 0;
28105  }
28106
28107 Property changes on: src/mod_usertrack.c
28108 ___________________________________________________________________
28109 Name: svn:eol-style
28110    + native
28111
28112 Index: src/http_auth_digest.h
28113 ===================================================================
28114 --- src/http_auth_digest.h      (.../tags/lighttpd-1.4.11)      (revision 1159)
28115 +++ src/http_auth_digest.h      (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
28116 @@ -12,7 +12,7 @@
28117  #ifdef USE_OPENSSL
28118  #define IN const
28119  #else
28120 -#define IN 
28121 +#define IN
28122  #endif
28123  #define OUT
28124  
28125
28126 Property changes on: src/http_auth_digest.h
28127 ___________________________________________________________________
28128 Name: svn:eol-style
28129    + native
28130
28131 Index: src/http_auth.h
28132 ===================================================================
28133 --- src/http_auth.h     (.../tags/lighttpd-1.4.11)      (revision 1159)
28134 +++ src/http_auth.h     (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
28135 @@ -9,22 +9,26 @@
28136  # include <ldap.h>
28137  #endif
28138  
28139 -typedef enum { AUTH_BACKEND_UNSET, AUTH_BACKEND_PLAIN, 
28140 -               AUTH_BACKEND_LDAP, AUTH_BACKEND_HTPASSWD, 
28141 -               AUTH_BACKEND_HTDIGEST, AUTH_BACKEND_PAM } auth_backend_t;
28142 +typedef enum {
28143 +       AUTH_BACKEND_UNSET,
28144 +       AUTH_BACKEND_PLAIN,
28145 +       AUTH_BACKEND_LDAP,
28146 +       AUTH_BACKEND_HTPASSWD,
28147 +       AUTH_BACKEND_HTDIGEST
28148 +} auth_backend_t;
28149  
28150  typedef struct {
28151         /* auth */
28152         array  *auth_require;
28153 -       
28154 +
28155         buffer *auth_plain_groupfile;
28156         buffer *auth_plain_userfile;
28157 -       
28158 +
28159         buffer *auth_htdigest_userfile;
28160         buffer *auth_htpasswd_userfile;
28161 -       
28162 +
28163         buffer *auth_backend_conf;
28164 -       
28165 +
28166         buffer *auth_ldap_hostname;
28167         buffer *auth_ldap_basedn;
28168         buffer *auth_ldap_binddn;
28169 @@ -32,15 +36,15 @@
28170         buffer *auth_ldap_filter;
28171         buffer *auth_ldap_cafile;
28172         unsigned short auth_ldap_starttls;
28173 -       
28174 +
28175         unsigned short auth_debug;
28176 -       
28177 +
28178         /* generated */
28179         auth_backend_t auth_backend;
28180 -       
28181 +
28182  #ifdef USE_LDAP
28183         LDAP *ldap;
28184 -       
28185 +
28186         buffer *ldap_filter_pre;
28187         buffer *ldap_filter_post;
28188  #endif
28189 @@ -49,15 +53,15 @@
28190  typedef struct {
28191         PLUGIN_DATA;
28192         buffer *tmp_buf;
28193 -       
28194 +
28195         buffer *auth_user;
28196  
28197  #ifdef USE_LDAP
28198         buffer *ldap_filter;
28199  #endif
28200 -       
28201 +
28202         mod_auth_plugin_config **config_storage;
28203 -       
28204 +
28205         mod_auth_plugin_config conf; /* this is only used as long as no handler_ctx is setup */
28206  } mod_auth_plugin_data;
28207  
28208
28209 Property changes on: src/http_auth.h
28210 ___________________________________________________________________
28211 Name: svn:eol-style
28212    + native
28213
28214 Index: src/mod_webdav.c
28215 ===================================================================
28216 --- src/mod_webdav.c    (.../tags/lighttpd-1.4.11)      (revision 1159)
28217 +++ src/mod_webdav.c    (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
28218 @@ -3,13 +3,10 @@
28219  #include <ctype.h>
28220  #include <stdlib.h>
28221  #include <string.h>
28222 -#include <dirent.h>
28223  #include <errno.h>
28224 -#include <unistd.h>
28225  #include <fcntl.h>
28226  #include <stdio.h>
28227  #include <assert.h>
28228 -#include <sys/mman.h>
28229  
28230  #ifdef HAVE_CONFIG_H
28231  #include "config.h"
28232 @@ -23,6 +20,11 @@
28233  #include <sqlite3.h>
28234  #endif
28235  
28236 +#if defined(HAVE_LIBXML_H) && defined(HAVE_SQLITE3_H) && defined(HAVE_UUID_H)
28237 +#define USE_LOCKS
28238 +#include <uuid/uuid.h>
28239 +#endif
28240 +
28241  #include "base.h"
28242  #include "log.h"
28243  #include "buffer.h"
28244 @@ -33,13 +35,16 @@
28245  #include "stream.h"
28246  #include "stat_cache.h"
28247  
28248 +#include "sys-files.h"
28249 +#include "sys-mmap.h"
28250 +#include "sys-strings.h"
28251  
28252  /**
28253   * this is a webdav for a lighttpd plugin
28254   *
28255 - * at least a very basic one. 
28256 + * at least a very basic one.
28257   * - for now it is read-only and we only support PROPFIND
28258 - * 
28259 + *
28260   */
28261  
28262  
28263 @@ -58,64 +63,70 @@
28264         sqlite3_stmt *stmt_delete_prop;
28265         sqlite3_stmt *stmt_select_prop;
28266         sqlite3_stmt *stmt_select_propnames;
28267 -       
28268 +
28269         sqlite3_stmt *stmt_delete_uri;
28270         sqlite3_stmt *stmt_move_uri;
28271         sqlite3_stmt *stmt_copy_uri;
28272 +
28273 +       sqlite3_stmt *stmt_remove_lock;
28274 +       sqlite3_stmt *stmt_create_lock;
28275 +       sqlite3_stmt *stmt_read_lock;
28276 +       sqlite3_stmt *stmt_read_lock_by_uri;
28277 +       sqlite3_stmt *stmt_refresh_lock;
28278  #endif
28279  } plugin_config;
28280  
28281  typedef struct {
28282         PLUGIN_DATA;
28283 -       
28284 +
28285         buffer *tmp_buf;
28286         request_uri uri;
28287         physical physical;
28288  
28289         plugin_config **config_storage;
28290 -       
28291 -       plugin_config conf; 
28292 +
28293 +       plugin_config conf;
28294  } plugin_data;
28295  
28296  /* init the plugin data */
28297  INIT_FUNC(mod_webdav_init) {
28298         plugin_data *p;
28299 -       
28300 +
28301         p = calloc(1, sizeof(*p));
28302 -       
28303 +
28304         p->tmp_buf = buffer_init();
28305  
28306         p->uri.scheme = buffer_init();
28307         p->uri.path_raw = buffer_init();
28308         p->uri.path = buffer_init();
28309         p->uri.authority = buffer_init();
28310 -       
28311 +
28312         p->physical.path = buffer_init();
28313         p->physical.rel_path = buffer_init();
28314         p->physical.doc_root = buffer_init();
28315         p->physical.basedir = buffer_init();
28316 -       
28317 +
28318         return p;
28319  }
28320  
28321  /* detroy the plugin data */
28322  FREE_FUNC(mod_webdav_free) {
28323         plugin_data *p = p_d;
28324 -       
28325 +
28326         UNUSED(srv);
28327  
28328         if (!p) return HANDLER_GO_ON;
28329 -       
28330 +
28331         if (p->config_storage) {
28332                 size_t i;
28333                 for (i = 0; i < srv->config_context->used; i++) {
28334                         plugin_config *s = p->config_storage[i];
28335  
28336                         if (!s) continue;
28337 -       
28338 +
28339                         buffer_free(s->sqlite_db_name);
28340  #ifdef USE_PROPPATCH
28341 -                       if (s->sql) {   
28342 +                       if (s->sql) {
28343                                 sqlite3_finalize(s->stmt_delete_prop);
28344                                 sqlite3_finalize(s->stmt_delete_uri);
28345                                 sqlite3_finalize(s->stmt_copy_uri);
28346 @@ -123,9 +134,15 @@
28347                                 sqlite3_finalize(s->stmt_update_prop);
28348                                 sqlite3_finalize(s->stmt_select_prop);
28349                                 sqlite3_finalize(s->stmt_select_propnames);
28350 +
28351 +                               sqlite3_finalize(s->stmt_read_lock);
28352 +                               sqlite3_finalize(s->stmt_read_lock_by_uri);
28353 +                               sqlite3_finalize(s->stmt_create_lock);
28354 +                               sqlite3_finalize(s->stmt_remove_lock);
28355 +                               sqlite3_finalize(s->stmt_refresh_lock);
28356                                 sqlite3_close(s->sql);
28357                         }
28358 -#endif 
28359 +#endif
28360                         free(s);
28361                 }
28362                 free(p->config_storage);
28363 @@ -135,16 +152,16 @@
28364         buffer_free(p->uri.path_raw);
28365         buffer_free(p->uri.path);
28366         buffer_free(p->uri.authority);
28367 -       
28368 +
28369         buffer_free(p->physical.path);
28370         buffer_free(p->physical.rel_path);
28371         buffer_free(p->physical.doc_root);
28372         buffer_free(p->physical.basedir);
28373 -       
28374 +
28375         buffer_free(p->tmp_buf);
28376 -       
28377 +
28378         free(p);
28379 -       
28380 +
28381         return HANDLER_GO_ON;
28382  }
28383  
28384 @@ -153,32 +170,32 @@
28385  SETDEFAULTS_FUNC(mod_webdav_set_defaults) {
28386         plugin_data *p = p_d;
28387         size_t i = 0;
28388 -       
28389 -       config_values_t cv[] = { 
28390 +
28391 +       config_values_t cv[] = {
28392                 { "webdav.activate",            NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
28393                 { "webdav.is-readonly",         NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
28394                 { "webdav.sqlite-db-name",      NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_CONNECTION },       /* 2 */
28395                 { "webdav.log-xml",             NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },       /* 3 */
28396                 { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
28397         };
28398 -       
28399 +
28400         if (!p) return HANDLER_ERROR;
28401 -       
28402 +
28403         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
28404 -       
28405 +
28406         for (i = 0; i < srv->config_context->used; i++) {
28407                 plugin_config *s;
28408 -               
28409 +
28410                 s = calloc(1, sizeof(plugin_config));
28411                 s->sqlite_db_name = buffer_init();
28412 -               
28413 +
28414                 cv[0].destination = &(s->enabled);
28415                 cv[1].destination = &(s->is_readonly);
28416                 cv[2].destination = s->sqlite_db_name;
28417                 cv[3].destination = &(s->log_xml);
28418 -               
28419 +
28420                 p->config_storage[i] = s;
28421 -       
28422 +
28423                 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
28424                         return HANDLER_ERROR;
28425                 }
28426 @@ -193,8 +210,26 @@
28427                                 return HANDLER_ERROR;
28428                         }
28429  
28430 -                       if (SQLITE_OK != sqlite3_prepare(s->sql, 
28431 -                               CONST_STR_LEN("SELECT value FROM properties WHERE resource = ? AND prop = ? AND ns = ?"), 
28432 +                       if (SQLITE_OK != sqlite3_exec(s->sql,
28433 +                                       "CREATE TABLE properties ("
28434 +                                       "  resource TEXT NOT NULL,"
28435 +                                       "  prop TEXT NOT NULL,"
28436 +                                       "  ns TEXT NOT NULL,"
28437 +                                       "  value TEXT NOT NULL,"
28438 +                                       "  PRIMARY KEY(resource, prop, ns))",
28439 +                                       NULL, NULL, &err)) {
28440 +
28441 +                               if (0 != strcmp(err, "table properties already exists")) {
28442 +                                       log_error_write(srv, __FILE__, __LINE__, "ss", "can't open transaction:", err);
28443 +                                       sqlite3_free(err);
28444 +
28445 +                                       return HANDLER_ERROR;
28446 +                               }
28447 +                               sqlite3_free(err);
28448 +                       }
28449 +
28450 +                       if (SQLITE_OK != sqlite3_prepare(s->sql,
28451 +                               CONST_STR_LEN("SELECT value FROM properties WHERE resource = ? AND prop = ? AND ns = ?"),
28452                                 &(s->stmt_select_prop), &next_stmt)) {
28453                                 /* prepare failed */
28454  
28455 @@ -202,8 +237,8 @@
28456                                 return HANDLER_ERROR;
28457                         }
28458  
28459 -                       if (SQLITE_OK != sqlite3_prepare(s->sql, 
28460 -                               CONST_STR_LEN("SELECT ns, prop FROM properties WHERE resource = ?"), 
28461 +                       if (SQLITE_OK != sqlite3_prepare(s->sql,
28462 +                               CONST_STR_LEN("SELECT ns, prop FROM properties WHERE resource = ?"),
28463                                 &(s->stmt_select_propnames), &next_stmt)) {
28464                                 /* prepare failed */
28465  
28466 @@ -211,16 +246,67 @@
28467                                 return HANDLER_ERROR;
28468                         }
28469  
28470 -                       if (SQLITE_OK != sqlite3_exec(s->sql, 
28471 -                                       "CREATE TABLE properties ("
28472 +
28473 +                       if (SQLITE_OK != sqlite3_prepare(s->sql,
28474 +                               CONST_STR_LEN("REPLACE INTO properties (resource, prop, ns, value) VALUES (?, ?, ?, ?)"),
28475 +                               &(s->stmt_update_prop), &next_stmt)) {
28476 +                               /* prepare failed */
28477 +
28478 +                               log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed:", sqlite3_errmsg(s->sql));
28479 +                               return HANDLER_ERROR;
28480 +                       }
28481 +
28482 +                       if (SQLITE_OK != sqlite3_prepare(s->sql,
28483 +                               CONST_STR_LEN("DELETE FROM properties WHERE resource = ? AND prop = ? AND ns = ?"),
28484 +                               &(s->stmt_delete_prop), &next_stmt)) {
28485 +                               /* prepare failed */
28486 +                               log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
28487 +
28488 +                               return HANDLER_ERROR;
28489 +                       }
28490 +
28491 +                       if (SQLITE_OK != sqlite3_prepare(s->sql,
28492 +                               CONST_STR_LEN("DELETE FROM properties WHERE resource = ?"),
28493 +                               &(s->stmt_delete_uri), &next_stmt)) {
28494 +                               /* prepare failed */
28495 +                               log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
28496 +
28497 +                               return HANDLER_ERROR;
28498 +                       }
28499 +
28500 +                       if (SQLITE_OK != sqlite3_prepare(s->sql,
28501 +                               CONST_STR_LEN("INSERT INTO properties SELECT ?, prop, ns, value FROM properties WHERE resource = ?"),
28502 +                               &(s->stmt_copy_uri), &next_stmt)) {
28503 +                               /* prepare failed */
28504 +                               log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
28505 +
28506 +                               return HANDLER_ERROR;
28507 +                       }
28508 +
28509 +                       if (SQLITE_OK != sqlite3_prepare(s->sql,
28510 +                               CONST_STR_LEN("UPDATE properties SET resource = ? WHERE resource = ?"),
28511 +                               &(s->stmt_move_uri), &next_stmt)) {
28512 +                               /* prepare failed */
28513 +                               log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
28514 +
28515 +                               return HANDLER_ERROR;
28516 +                       }
28517 +
28518 +                       /* LOCKS */
28519 +
28520 +                       if (SQLITE_OK != sqlite3_exec(s->sql,
28521 +                                       "CREATE TABLE locks ("
28522 +                                       "  locktoken TEXT NOT NULL,"
28523                                         "  resource TEXT NOT NULL,"
28524 -                                       "  prop TEXT NOT NULL,"
28525 -                                       "  ns TEXT NOT NULL,"
28526 -                                       "  value TEXT NOT NULL,"
28527 -                                       "  PRIMARY KEY(resource, prop, ns))",
28528 +                                       "  lockscope TEXT NOT NULL,"
28529 +                                       "  locktype TEXT NOT NULL,"
28530 +                                       "  owner TEXT NOT NULL,"
28531 +                                       "  depth INT NOT NULL,"
28532 +                                       "  timeout TIMESTAMP NOT NULL,"
28533 +                                       "  PRIMARY KEY(locktoken))",
28534                                         NULL, NULL, &err)) {
28535  
28536 -                               if (0 != strcmp(err, "table properties already exists")) {
28537 +                               if (0 != strcmp(err, "table locks already exists")) {
28538                                         log_error_write(srv, __FILE__, __LINE__, "ss", "can't open transaction:", err);
28539                                         sqlite3_free(err);
28540  
28541 @@ -228,127 +314,138 @@
28542                                 }
28543                                 sqlite3_free(err);
28544                         }
28545 -       
28546 -                       if (SQLITE_OK != sqlite3_prepare(s->sql, 
28547 -                               CONST_STR_LEN("REPLACE INTO properties (resource, prop, ns, value) VALUES (?, ?, ?, ?)"), 
28548 -                               &(s->stmt_update_prop), &next_stmt)) {
28549 +
28550 +                       if (SQLITE_OK != sqlite3_prepare(s->sql,
28551 +                               CONST_STR_LEN("INSERT INTO locks (locktoken, resource, lockscope, locktype, owner, depth, timeout) VALUES (?,?,?,?,?,?, CURRENT_TIME + 600)"),
28552 +                               &(s->stmt_create_lock), &next_stmt)) {
28553                                 /* prepare failed */
28554 +                               log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
28555  
28556 -                               log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed:", sqlite3_errmsg(s->sql));
28557                                 return HANDLER_ERROR;
28558                         }
28559  
28560 -                       if (SQLITE_OK != sqlite3_prepare(s->sql, 
28561 -                               CONST_STR_LEN("DELETE FROM properties WHERE resource = ? AND prop = ? AND ns = ?"), 
28562 -                               &(s->stmt_delete_prop), &next_stmt)) {
28563 +                       if (SQLITE_OK != sqlite3_prepare(s->sql,
28564 +                               CONST_STR_LEN("DELETE FROM locks WHERE locktoken = ?"),
28565 +                               &(s->stmt_remove_lock), &next_stmt)) {
28566                                 /* prepare failed */
28567                                 log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
28568  
28569                                 return HANDLER_ERROR;
28570                         }
28571  
28572 -                       if (SQLITE_OK != sqlite3_prepare(s->sql, 
28573 -                               CONST_STR_LEN("DELETE FROM properties WHERE resource = ?"), 
28574 -                               &(s->stmt_delete_uri), &next_stmt)) {
28575 +                       if (SQLITE_OK != sqlite3_prepare(s->sql,
28576 +                               CONST_STR_LEN("SELECT locktoken, resource, lockscope, locktype, owner, depth, timeout FROM locks WHERE locktoken = ?"),
28577 +                               &(s->stmt_read_lock), &next_stmt)) {
28578                                 /* prepare failed */
28579                                 log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
28580  
28581                                 return HANDLER_ERROR;
28582                         }
28583  
28584 -                       if (SQLITE_OK != sqlite3_prepare(s->sql, 
28585 -                               CONST_STR_LEN("INSERT INTO properties SELECT ?, prop, ns, value FROM properties WHERE resource = ?"), 
28586 -                               &(s->stmt_copy_uri), &next_stmt)) {
28587 +                       if (SQLITE_OK != sqlite3_prepare(s->sql,
28588 +                               CONST_STR_LEN("SELECT locktoken, resource, lockscope, locktype, owner, depth, timeout FROM locks WHERE resource = ?"),
28589 +                               &(s->stmt_read_lock_by_uri), &next_stmt)) {
28590                                 /* prepare failed */
28591                                 log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
28592  
28593                                 return HANDLER_ERROR;
28594                         }
28595  
28596 -                       if (SQLITE_OK != sqlite3_prepare(s->sql, 
28597 -                               CONST_STR_LEN("UPDATE properties SET resource = ? WHERE resource = ?"), 
28598 -                               &(s->stmt_move_uri), &next_stmt)) {
28599 +                       if (SQLITE_OK != sqlite3_prepare(s->sql,
28600 +                               CONST_STR_LEN("UPDATE locks SET timeout = CURRENT_TIME + 600 WHERE locktoken = ?"),
28601 +                               &(s->stmt_refresh_lock), &next_stmt)) {
28602                                 /* prepare failed */
28603                                 log_error_write(srv, __FILE__, __LINE__, "ss", "sqlite3_prepare failed", sqlite3_errmsg(s->sql));
28604  
28605                                 return HANDLER_ERROR;
28606                         }
28607 +
28608 +
28609  #else
28610                         log_error_write(srv, __FILE__, __LINE__, "s", "Sorry, no sqlite3 and libxml2 support include, compile with --with-webdav-props");
28611                         return HANDLER_ERROR;
28612  #endif
28613                 }
28614         }
28615 -       
28616 +
28617         return HANDLER_GO_ON;
28618  }
28619  
28620 -#define PATCH(x) \
28621 -       p->conf.x = s->x;
28622  static int mod_webdav_patch_connection(server *srv, connection *con, plugin_data *p) {
28623         size_t i, j;
28624         plugin_config *s = p->config_storage[0];
28625 -       
28626 -       PATCH(enabled);
28627 -       PATCH(is_readonly);
28628 -       PATCH(log_xml);
28629 -       
28630 +
28631 +       PATCH_OPTION(enabled);
28632 +       PATCH_OPTION(is_readonly);
28633 +       PATCH_OPTION(log_xml);
28634 +
28635  #ifdef USE_PROPPATCH
28636 -       PATCH(sql);
28637 -       PATCH(stmt_update_prop);
28638 -       PATCH(stmt_delete_prop);
28639 -       PATCH(stmt_select_prop);
28640 -       PATCH(stmt_select_propnames);
28641 +       PATCH_OPTION(sql);
28642 +       PATCH_OPTION(stmt_update_prop);
28643 +       PATCH_OPTION(stmt_delete_prop);
28644 +       PATCH_OPTION(stmt_select_prop);
28645 +       PATCH_OPTION(stmt_select_propnames);
28646  
28647 -       PATCH(stmt_delete_uri);
28648 -       PATCH(stmt_move_uri);
28649 -       PATCH(stmt_copy_uri);
28650 +       PATCH_OPTION(stmt_delete_uri);
28651 +       PATCH_OPTION(stmt_move_uri);
28652 +       PATCH_OPTION(stmt_copy_uri);
28653 +
28654 +       PATCH_OPTION(stmt_remove_lock);
28655 +       PATCH_OPTION(stmt_refresh_lock);
28656 +       PATCH_OPTION(stmt_create_lock);
28657 +       PATCH_OPTION(stmt_read_lock);
28658 +       PATCH_OPTION(stmt_read_lock_by_uri);
28659  #endif
28660         /* skip the first, the global context */
28661         for (i = 1; i < srv->config_context->used; i++) {
28662                 data_config *dc = (data_config *)srv->config_context->data[i];
28663                 s = p->config_storage[i];
28664 -               
28665 +
28666                 /* condition didn't match */
28667                 if (!config_check_cond(srv, con, dc)) continue;
28668 -               
28669 +
28670                 /* merge config */
28671                 for (j = 0; j < dc->value->used; j++) {
28672                         data_unset *du = dc->value->data[j];
28673 -                       
28674 +
28675                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("webdav.activate"))) {
28676 -                               PATCH(enabled);
28677 +                               PATCH_OPTION(enabled);
28678                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("webdav.is-readonly"))) {
28679 -                               PATCH(is_readonly);
28680 +                               PATCH_OPTION(is_readonly);
28681                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("webdav.log-xml"))) {
28682 -                               PATCH(log_xml);
28683 +                               PATCH_OPTION(log_xml);
28684                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("webdav.sqlite-db-name"))) {
28685  #ifdef USE_PROPPATCH
28686 -                               PATCH(sql);
28687 -                               PATCH(stmt_update_prop);
28688 -                               PATCH(stmt_delete_prop);
28689 -                               PATCH(stmt_select_prop);
28690 -                               PATCH(stmt_select_propnames);
28691 -                               
28692 -                               PATCH(stmt_delete_uri);
28693 -                               PATCH(stmt_move_uri);
28694 -                               PATCH(stmt_copy_uri);
28695 +                               PATCH_OPTION(sql);
28696 +                               PATCH_OPTION(stmt_update_prop);
28697 +                               PATCH_OPTION(stmt_delete_prop);
28698 +                               PATCH_OPTION(stmt_select_prop);
28699 +                               PATCH_OPTION(stmt_select_propnames);
28700 +
28701 +                               PATCH_OPTION(stmt_delete_uri);
28702 +                               PATCH_OPTION(stmt_move_uri);
28703 +                               PATCH_OPTION(stmt_copy_uri);
28704 +
28705 +                               PATCH_OPTION(stmt_remove_lock);
28706 +                               PATCH_OPTION(stmt_refresh_lock);
28707 +                               PATCH_OPTION(stmt_create_lock);
28708 +                               PATCH_OPTION(stmt_read_lock);
28709 +                               PATCH_OPTION(stmt_read_lock_by_uri);
28710  #endif
28711                         }
28712                 }
28713         }
28714 -       
28715 +
28716         return 0;
28717  }
28718 -#undef PATCH
28719  
28720  URIHANDLER_FUNC(mod_webdav_uri_handler) {
28721         plugin_data *p = p_d;
28722 -       
28723 +
28724         UNUSED(srv);
28725  
28726         if (con->uri.path->used == 0) return HANDLER_GO_ON;
28727 -       
28728 +
28729         mod_webdav_patch_connection(srv, con, p);
28730  
28731         if (!p->conf.enabled) return HANDLER_GO_ON;
28732 @@ -362,20 +459,20 @@
28733                 if (p->conf.is_readonly) {
28734                         response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("PROPFIND"));
28735                 } else {
28736 -                       response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("PROPFIND, DELETE, MKCOL, PUT, MOVE, COPY, PROPPATCH"));
28737 +                       response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("PROPFIND, DELETE, MKCOL, PUT, MOVE, COPY, PROPPATCH, LOCK, UNLOCK"));
28738                 }
28739                 break;
28740         default:
28741                 break;
28742         }
28743 -       
28744 +
28745         /* not found */
28746         return HANDLER_GO_ON;
28747  }
28748 -static int webdav_gen_prop_tag(server *srv, connection *con, 
28749 -               char *prop_name, 
28750 -               char *prop_ns, 
28751 -               char *value, 
28752 +static int webdav_gen_prop_tag(server *srv, connection *con,
28753 +               char *prop_name,
28754 +               char *prop_ns,
28755 +               char *value,
28756                 buffer *b) {
28757  
28758         UNUSED(srv);
28759 @@ -414,7 +511,7 @@
28760         buffer_append_string_buffer(b, dst->rel_path);
28761         buffer_append_string(b,"</D:href>\n");
28762         buffer_append_string(b,"<D:status>\n");
28763 -       
28764 +
28765         if (con->request.http_version == HTTP_VERSION_1_1) {
28766                 BUFFER_COPY_STRING_CONST(b, "HTTP/1.1 ");
28767         } else {
28768 @@ -458,11 +555,11 @@
28769  
28770                         /* bind the values to the insert */
28771  
28772 -                       sqlite3_bind_text(stmt, 1, 
28773 -                                         dst->rel_path->ptr, 
28774 +                       sqlite3_bind_text(stmt, 1,
28775 +                                         dst->rel_path->ptr,
28776                                           dst->rel_path->used - 1,
28777                                           SQLITE_TRANSIENT);
28778 -                                                                       
28779 +
28780                         if (SQLITE_DONE != sqlite3_step(stmt)) {
28781                                 /* */
28782                                 WP();
28783 @@ -493,14 +590,14 @@
28784                             (de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0')) {
28785                                 continue;
28786                                 /* ignore the parent dir */
28787 -                       } 
28788 +                       }
28789  
28790                         buffer_copy_string_buffer(d.path, dst->path);
28791 -                       BUFFER_APPEND_SLASH(d.path);
28792 +                       PATHNAME_APPEND_SLASH(d.path);
28793                         buffer_append_string(d.path, de->d_name);
28794 -                       
28795 +
28796                         buffer_copy_string_buffer(d.rel_path, dst->rel_path);
28797 -                       BUFFER_APPEND_SLASH(d.rel_path);
28798 +                       PATHNAME_APPEND_SLASH(d.rel_path);
28799                         buffer_append_string(d.rel_path, de->d_name);
28800  
28801                         /* stat and unlink afterwards */
28802 @@ -508,7 +605,7 @@
28803                                 /* don't about it yet, rmdir will fail too */
28804                         } else if (S_ISDIR(st.st_mode)) {
28805                                 have_multi_status = webdav_delete_dir(srv, con, p, &d, b);
28806 -                                       
28807 +
28808                                 /* try to unlink it */
28809                                 if (-1 == rmdir(d.path->ptr)) {
28810                                         switch(errno) {
28811 @@ -535,11 +632,11 @@
28812  
28813                                                 /* bind the values to the insert */
28814  
28815 -                                               sqlite3_bind_text(stmt, 1, 
28816 -                                                                 d.rel_path->ptr, 
28817 +                                               sqlite3_bind_text(stmt, 1,
28818 +                                                                 d.rel_path->ptr,
28819                                                                   d.rel_path->used - 1,
28820                                                                   SQLITE_TRANSIENT);
28821 -                                                                                                       
28822 +
28823                                                 if (SQLITE_DONE != sqlite3_step(stmt)) {
28824                                                         /* */
28825                                                         WP();
28826 @@ -569,7 +666,7 @@
28827         if (stream_open(&s, src->path)) {
28828                 return 403;
28829         }
28830 -                       
28831 +
28832         if (-1 == (ofd = open(dst->path->ptr, O_WRONLY|O_TRUNC|O_CREAT|(overwrite ? 0 : O_EXCL), 0600))) {
28833                 /* opening the destination failed for some reason */
28834                 switch(errno) {
28835 @@ -601,7 +698,7 @@
28836                         break;
28837                 }
28838         }
28839 -       
28840 +
28841         stream_close(&s);
28842         close(ofd);
28843  
28844 @@ -614,16 +711,16 @@
28845                         sqlite3_reset(stmt);
28846  
28847                         /* bind the values to the insert */
28848 -                       sqlite3_bind_text(stmt, 1, 
28849 -                                         dst->rel_path->ptr, 
28850 +                       sqlite3_bind_text(stmt, 1,
28851 +                                         dst->rel_path->ptr,
28852                                           dst->rel_path->used - 1,
28853                                           SQLITE_TRANSIENT);
28854  
28855 -                       sqlite3_bind_text(stmt, 2, 
28856 -                                         src->rel_path->ptr, 
28857 +                       sqlite3_bind_text(stmt, 2,
28858 +                                         src->rel_path->ptr,
28859                                           src->rel_path->used - 1,
28860                                           SQLITE_TRANSIENT);
28861 -                                                                                                       
28862 +
28863                         if (SQLITE_DONE != sqlite3_step(stmt)) {
28864                                 /* */
28865                                 WP();
28866 @@ -655,21 +752,21 @@
28867                             (de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0')) {
28868                                 continue;
28869                         }
28870 -                       
28871 +
28872                         buffer_copy_string_buffer(s.path, src->path);
28873 -                       BUFFER_APPEND_SLASH(s.path);
28874 +                       PATHNAME_APPEND_SLASH(s.path);
28875                         buffer_append_string(s.path, de->d_name);
28876  
28877                         buffer_copy_string_buffer(d.path, dst->path);
28878 -                       BUFFER_APPEND_SLASH(d.path);
28879 +                       PATHNAME_APPEND_SLASH(d.path);
28880                         buffer_append_string(d.path, de->d_name);
28881  
28882                         buffer_copy_string_buffer(s.rel_path, src->rel_path);
28883 -                       BUFFER_APPEND_SLASH(s.rel_path);
28884 +                       PATHNAME_APPEND_SLASH(s.rel_path);
28885                         buffer_append_string(s.rel_path, de->d_name);
28886  
28887                         buffer_copy_string_buffer(d.rel_path, dst->rel_path);
28888 -                       BUFFER_APPEND_SLASH(d.rel_path);
28889 +                       PATHNAME_APPEND_SLASH(d.rel_path);
28890                         buffer_append_string(d.rel_path, de->d_name);
28891  
28892                         if (-1 == stat(s.path->ptr, &st)) {
28893 @@ -692,16 +789,16 @@
28894                                                 sqlite3_reset(stmt);
28895  
28896                                                 /* bind the values to the insert */
28897 -                                               sqlite3_bind_text(stmt, 1, 
28898 -                                                         dst->rel_path->ptr, 
28899 +                                               sqlite3_bind_text(stmt, 1,
28900 +                                                         dst->rel_path->ptr,
28901                                                           dst->rel_path->used - 1,
28902                                                           SQLITE_TRANSIENT);
28903  
28904 -                                               sqlite3_bind_text(stmt, 2, 
28905 -                                                         src->rel_path->ptr, 
28906 +                                               sqlite3_bind_text(stmt, 2,
28907 +                                                         src->rel_path->ptr,
28908                                                           src->rel_path->used - 1,
28909                                                           SQLITE_TRANSIENT);
28910 -                                                                                                       
28911 +
28912                                                 if (SQLITE_DONE != sqlite3_step(stmt)) {
28913                                                         /* */
28914                                                         WP();
28915 @@ -721,7 +818,7 @@
28916                 buffer_free(s.rel_path);
28917                 buffer_free(d.path);
28918                 buffer_free(d.rel_path);
28919 -               
28920 +
28921                 closedir(srcdir);
28922         }
28923  
28924 @@ -748,12 +845,12 @@
28925                         if (S_ISDIR(sce->st.st_mode)) {
28926                                 buffer_append_string(b, "<D:getcontenttype>httpd/unix-directory</D:getcontenttype>");
28927                                 found = 1;
28928 -                       } else if(S_ISREG(sce->st.st_mode)) { 
28929 +                       } else if(S_ISREG(sce->st.st_mode)) {
28930                                 for (k = 0; k < con->conf.mimetypes->used; k++) {
28931                                         data_string *ds = (data_string *)con->conf.mimetypes->data[k];
28932 -               
28933 +
28934                                         if (ds->key->used == 0) continue;
28935 -                               
28936 +
28937                                         if (buffer_is_equal_right_len(dst->path, ds->key, ds->key->used - 1)) {
28938                                                 buffer_append_string(b,"<D:getcontenttype>");
28939                                                 buffer_append_string_buffer(b, ds->value);
28940 @@ -807,23 +904,23 @@
28941  
28942                         /* bind the values to the insert */
28943  
28944 -                       sqlite3_bind_text(stmt, 1, 
28945 -                                         dst->rel_path->ptr, 
28946 +                       sqlite3_bind_text(stmt, 1,
28947 +                                         dst->rel_path->ptr,
28948                                           dst->rel_path->used - 1,
28949                                           SQLITE_TRANSIENT);
28950 -                       sqlite3_bind_text(stmt, 2, 
28951 +                       sqlite3_bind_text(stmt, 2,
28952                                           prop_name,
28953                                           strlen(prop_name),
28954                                           SQLITE_TRANSIENT);
28955 -                       sqlite3_bind_text(stmt, 3, 
28956 +                       sqlite3_bind_text(stmt, 3,
28957                                           prop_ns,
28958                                           strlen(prop_ns),
28959                                           SQLITE_TRANSIENT);
28960  
28961                         /* it is the PK */
28962 -                       while (SQLITE_ROW == sqlite3_step(p->conf.stmt_select_prop)) {
28963 +                       while (SQLITE_ROW == sqlite3_step(stmt)) {
28964                                 /* there is a row for us, we only expect a single col 'value' */
28965 -                               webdav_gen_prop_tag(srv, con, prop_name, prop_ns, (char *)sqlite3_column_text(p->conf.stmt_select_prop, 0), b);
28966 +                               webdav_gen_prop_tag(srv, con, prop_name, prop_ns, (char *)sqlite3_column_text(stmt, 0), b);
28967                                 found = 1;
28968                         }
28969                 }
28970 @@ -840,7 +937,7 @@
28971         char *prop;
28972  } webdav_property;
28973  
28974 -webdav_property live_properties[] = { 
28975 +webdav_property live_properties[] = {
28976         { "DAV:", "creationdate" },
28977         { "DAV:", "displayname" },
28978         { "DAV:", "getcontentlanguage" },
28979 @@ -871,8 +968,8 @@
28980                         webdav_property *prop;
28981  
28982                         prop = props->ptr[i];
28983 -                       
28984 -                       if (0 != webdav_get_property(srv, con, p, 
28985 +
28986 +                       if (0 != webdav_get_property(srv, con, p,
28987                                 dst, prop->prop, prop->ns, b_200)) {
28988                                 webdav_gen_prop_tag(srv, con, prop->prop, prop->ns, NULL, b_404);
28989                         }
28990 @@ -916,12 +1013,12 @@
28991                                 if (-1 == c->file.fd &&  /* open the file if not already open */
28992                                     -1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) {
28993                                         log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
28994 -               
28995 +
28996                                         return -1;
28997                                 }
28998 -       
28999 +
29000                                 if (MAP_FAILED == (c->file.mmap.start = mmap(0, c->file.length, PROT_READ, MAP_SHARED, c->file.fd, 0))) {
29001 -                                       log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed: ", 
29002 +                                       log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed: ",
29003                                                         strerror(errno), c->file.name,  c->file.fd);
29004  
29005                                         return -1;
29006 @@ -938,7 +1035,7 @@
29007                         if (XML_ERR_OK != (err = xmlParseChunk(ctxt, c->file.mmap.start + c->offset, weHave, 0))) {
29008                                 log_error_write(srv, __FILE__, __LINE__, "sddd", "xmlParseChunk failed at:", cq->bytes_out, weHave, err);
29009                         }
29010 -                       
29011 +
29012                         c->offset += weHave;
29013                         cq->bytes_out += weHave;
29014  
29015 @@ -956,7 +1053,7 @@
29016                         if (XML_ERR_OK != (err = xmlParseChunk(ctxt, c->mem->ptr + c->offset, weHave, 0))) {
29017                                 log_error_write(srv, __FILE__, __LINE__, "sddd", "xmlParseChunk failed at:", cq->bytes_out, weHave, err);
29018                         }
29019 -                       
29020 +
29021                         c->offset += weHave;
29022                         cq->bytes_out += weHave;
29023  
29024 @@ -991,6 +1088,113 @@
29025  }
29026  #endif
29027  
29028 +int webdav_lockdiscovery(server *srv, connection *con,
29029 +               buffer *locktoken, const char *lockscope, const char *locktype, int depth) {
29030 +
29031 +       buffer *b;
29032 +
29033 +       response_header_overwrite(srv, con, CONST_STR_LEN("Lock-Token"), CONST_BUF_LEN(locktoken));
29034 +
29035 +       response_header_overwrite(srv, con,
29036 +               CONST_STR_LEN("Content-Type"),
29037 +               CONST_STR_LEN("text/xml; charset=\"utf-8\""));
29038 +
29039 +       b = chunkqueue_get_append_buffer(con->write_queue);
29040 +
29041 +       buffer_copy_string(b, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
29042 +
29043 +       buffer_append_string(b,"<D:prop xmlns:D=\"DAV:\" xmlns:ns0=\"urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/\">\n");
29044 +       buffer_append_string(b,"<D:lockdiscovery>\n");
29045 +       buffer_append_string(b,"<D:activelock>\n");
29046 +
29047 +       buffer_append_string(b,"<D:lockscope>");
29048 +       buffer_append_string(b,"<D:");
29049 +       buffer_append_string(b, lockscope);
29050 +       buffer_append_string(b, "/>");
29051 +       buffer_append_string(b,"</D:lockscope>\n");
29052 +
29053 +       buffer_append_string(b,"<D:locktype>");
29054 +       buffer_append_string(b,"<D:");
29055 +       buffer_append_string(b, locktype);
29056 +       buffer_append_string(b, "/>");
29057 +       buffer_append_string(b,"</D:locktype>\n");
29058 +
29059 +       buffer_append_string(b,"<D:depth>");
29060 +       buffer_append_string(b, depth == 0 ? "0" : "infinity");
29061 +       buffer_append_string(b,"</D:depth>\n");
29062 +
29063 +       buffer_append_string(b,"<D:timeout>");
29064 +       buffer_append_string(b, "Second-600");
29065 +       buffer_append_string(b,"</D:timeout>\n");
29066 +
29067 +       buffer_append_string(b,"<D:owner>");
29068 +       buffer_append_string(b,"</D:owner>\n");
29069 +
29070 +       buffer_append_string(b,"<D:locktoken>");
29071 +       buffer_append_string(b, "<D:href>");
29072 +       buffer_append_string_buffer(b, locktoken);
29073 +       buffer_append_string(b, "</D:href>");
29074 +       buffer_append_string(b,"</D:locktoken>\n");
29075 +
29076 +       buffer_append_string(b,"</D:activelock>\n");
29077 +       buffer_append_string(b,"</D:lockdiscovery>\n");
29078 +       buffer_append_string(b,"</D:prop>\n");
29079 +
29080 +       return 0;
29081 +}
29082 +/**
29083 + * check if resource is having the right locks to access to resource
29084 + *
29085 + *
29086 + *
29087 + */
29088 +int webdav_has_lock(server *srv, connection *con, plugin_data *p, buffer *uri) {
29089 +       int has_lock = 1;
29090 +
29091 +#ifdef USE_LOCKS
29092 +       data_string *ds;
29093 +
29094 +       /**
29095 +        * If can have
29096 +        * - <lock-token>
29097 +        * - [etag]
29098 +        *
29099 +        * there is NOT, AND and OR
29100 +        * and a list can be tagged
29101 +        *
29102 +        * (<lock-token>) is untagged
29103 +        * <tag> (<lock-token>) is tagged
29104 +        *
29105 +        * as long as we don't handle collections it is simple. :)
29106 +        *
29107 +        * X-Litmus: locks: 11 (owner_modify)
29108 +        * If: <http://127.0.0.1:1025/dav/litmus/lockme> (<opaquelocktoken:2165478d-0611-49c4-be92-e790d68a38f1>)
29109 +        *
29110 +        * X-Litmus: locks: 16 (fail_cond_put)
29111 +        * If: (<DAV:no-lock> ["-1622396671"])
29112 +        */
29113 +       if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "If"))) {
29114 +       } else {
29115 +               /* we didn't provided a lock-token -> */
29116 +               /* if the resource is locked -> 423 */
29117 +
29118 +               sqlite3_stmt *stmt = p->conf.stmt_read_lock_by_uri;
29119 +
29120 +               sqlite3_reset(stmt);
29121 +
29122 +               sqlite3_bind_text(stmt, 1,
29123 +                         CONST_BUF_LEN(uri),
29124 +                         SQLITE_TRANSIENT);
29125 +
29126 +               while (SQLITE_ROW == sqlite3_step(stmt)) {
29127 +                       has_lock = 0;
29128 +               }
29129 +       }
29130 +#endif
29131 +
29132 +       return has_lock;
29133 +}
29134 +
29135  URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
29136         plugin_data *p = p_d;
29137         buffer *b;
29138 @@ -1001,7 +1205,8 @@
29139         buffer *prop_200;
29140         buffer *prop_404;
29141         webdav_properties *req_props;
29142 -       
29143 +       stat_cache_entry *sce = NULL;
29144 +
29145         UNUSED(srv);
29146  
29147         if (!p->conf.enabled) return HANDLER_GO_ON;
29148 @@ -1019,7 +1224,19 @@
29149                 req_props = NULL;
29150  
29151                 /* is there a content-body ? */
29152 -       
29153 +
29154 +               switch (stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
29155 +               case HANDLER_ERROR:
29156 +                       if (errno == ENOENT) {
29157 +                               con->http_status = 404;
29158 +                               return HANDLER_FINISHED;
29159 +                       }
29160 +                       break;
29161 +               default:
29162 +                       break;
29163 +               }
29164 +
29165 +
29166  #ifdef USE_PROPPATCH
29167                 /* any special requests or just allprop ? */
29168                 if (con->request.content_length) {
29169 @@ -1087,12 +1304,12 @@
29170                                                                 /* get all property names (EMPTY) */
29171                                                                 sqlite3_reset(stmt);
29172                                                                 /* bind the values to the insert */
29173 -       
29174 -                                                               sqlite3_bind_text(stmt, 1, 
29175 -                                                                                 con->uri.path->ptr, 
29176 +
29177 +                                                               sqlite3_bind_text(stmt, 1,
29178 +                                                                                 con->uri.path->ptr,
29179                                                                                   con->uri.path->used - 1,
29180                                                                                   SQLITE_TRANSIENT);
29181 -                                               
29182 +
29183                                                                 if (SQLITE_DONE != sqlite3_step(stmt)) {
29184                                                                         WP();
29185                                                                 }
29186 @@ -1115,13 +1332,13 @@
29187                 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
29188  
29189                 b = chunkqueue_get_append_buffer(con->write_queue);
29190 -                               
29191 +
29192                 buffer_copy_string(b, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
29193  
29194                 buffer_append_string(b,"<D:multistatus xmlns:D=\"DAV:\" xmlns:ns0=\"urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/\">\n");
29195  
29196                 /* allprop */
29197 -               
29198 +
29199                 prop_200 = buffer_init();
29200                 prop_404 = buffer_init();
29201  
29202 @@ -1129,7 +1346,7 @@
29203                 case 0:
29204                         /* Depth: 0 */
29205                         webdav_get_props(srv, con, p, &(con->physical), req_props, prop_200, prop_404);
29206 -       
29207 +
29208                         buffer_append_string(b,"<D:response>\n");
29209                         buffer_append_string(b,"<D:href>");
29210                         buffer_append_string_buffer(b, con->uri.scheme);
29211 @@ -1145,9 +1362,9 @@
29212                                 buffer_append_string_buffer(b, prop_200);
29213  
29214                                 buffer_append_string(b,"</D:prop>\n");
29215 -       
29216 +
29217                                 buffer_append_string(b,"<D:status>HTTP/1.1 200 OK</D:status>\n");
29218 -       
29219 +
29220                                 buffer_append_string(b,"</D:propstat>\n");
29221                         }
29222                         if (!buffer_is_empty(prop_404)) {
29223 @@ -1157,16 +1374,16 @@
29224                                 buffer_append_string_buffer(b, prop_404);
29225  
29226                                 buffer_append_string(b,"</D:prop>\n");
29227 -       
29228 +
29229                                 buffer_append_string(b,"<D:status>HTTP/1.1 404 Not Found</D:status>\n");
29230 -       
29231 +
29232                                 buffer_append_string(b,"</D:propstat>\n");
29233                         }
29234  
29235                         buffer_append_string(b,"</D:response>\n");
29236  
29237                         break;
29238 -               case 1: 
29239 +               case 1:
29240                         if (NULL != (dir = opendir(con->physical.path->ptr))) {
29241                                 struct dirent *de;
29242                                 physical d;
29243 @@ -1179,16 +1396,16 @@
29244                                         if (de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0') {
29245                                                 continue;
29246                                                 /* ignore the parent dir */
29247 -                                       } 
29248 +                                       }
29249  
29250                                         buffer_copy_string_buffer(d.path, dst->path);
29251 -                                       BUFFER_APPEND_SLASH(d.path);
29252 +                                       PATHNAME_APPEND_SLASH(d.path);
29253  
29254                                         buffer_copy_string_buffer(d.rel_path, dst->rel_path);
29255 -                                       BUFFER_APPEND_SLASH(d.rel_path);
29256 +                                       PATHNAME_APPEND_SLASH(d.rel_path);
29257  
29258                                         if (de->d_name[0] == '.' && de->d_name[1] == '\0') {
29259 -                                               /* don't append the . */ 
29260 +                                               /* don't append the . */
29261                                         } else {
29262                                                 buffer_append_string(d.path, de->d_name);
29263                                                 buffer_append_string(d.rel_path, de->d_name);
29264 @@ -1198,7 +1415,7 @@
29265                                         buffer_reset(prop_404);
29266  
29267                                         webdav_get_props(srv, con, p, &d, req_props, prop_200, prop_404);
29268 -                                       
29269 +
29270                                         buffer_append_string(b,"<D:response>\n");
29271                                         buffer_append_string(b,"<D:href>");
29272                                         buffer_append_string_buffer(b, con->uri.scheme);
29273 @@ -1214,9 +1431,9 @@
29274                                                 buffer_append_string_buffer(b, prop_200);
29275  
29276                                                 buffer_append_string(b,"</D:prop>\n");
29277 -                       
29278 +
29279                                                 buffer_append_string(b,"<D:status>HTTP/1.1 200 OK</D:status>\n");
29280 -                       
29281 +
29282                                                 buffer_append_string(b,"</D:propstat>\n");
29283                                         }
29284                                         if (!buffer_is_empty(prop_404)) {
29285 @@ -1226,9 +1443,9 @@
29286                                                 buffer_append_string_buffer(b, prop_404);
29287  
29288                                                 buffer_append_string(b,"</D:prop>\n");
29289 -       
29290 +
29291                                                 buffer_append_string(b,"<D:status>HTTP/1.1 404 Not Found</D:status>\n");
29292 -       
29293 +
29294                                                 buffer_append_string(b,"</D:propstat>\n");
29295                                         }
29296  
29297 @@ -1275,7 +1492,7 @@
29298  
29299                         return HANDLER_FINISHED;
29300                 }
29301 -       
29302 +
29303                 /* let's create the directory */
29304  
29305                 if (-1 == mkdir(con->physical.path->ptr, 0700)) {
29306 @@ -1303,7 +1520,13 @@
29307                         con->http_status = 403;
29308                         return HANDLER_FINISHED;
29309                 }
29310 -               
29311 +
29312 +               /* does the client have a lock for this connection ? */
29313 +               if (!webdav_has_lock(srv, con, p, con->uri.path)) {
29314 +                       con->http_status = 423;
29315 +                       return HANDLER_FINISHED;
29316 +               }
29317 +
29318                 /* stat and unlink afterwards */
29319                 if (-1 == stat(con->physical.path->ptr, &st)) {
29320                         /* don't about it yet, unlink will fail too */
29321 @@ -1323,7 +1546,7 @@
29322                                 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
29323  
29324                                 b = chunkqueue_get_append_buffer(con->write_queue);
29325 -                       
29326 +
29327                                 buffer_copy_string(b, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
29328  
29329                                 buffer_append_string(b,"<D:multistatus xmlns:D=\"DAV:\">\n");
29330 @@ -1331,7 +1554,7 @@
29331                                 buffer_append_string_buffer(b, multi_status_resp);
29332  
29333                                 buffer_append_string(b,"</D:multistatus>\n");
29334 -                       
29335 +
29336                                 if (p->conf.log_xml) {
29337                                         log_error_write(srv, __FILE__, __LINE__, "sb", "XML-response-body:", b);
29338                                 }
29339 @@ -1340,7 +1563,7 @@
29340                                 con->file_finished = 1;
29341                         } else {
29342                                 /* everything went fine, remove the directory */
29343 -       
29344 +
29345                                 if (-1 == rmdir(con->physical.path->ptr)) {
29346                                         switch(errno) {
29347                                         case ENOENT:
29348 @@ -1375,97 +1598,174 @@
29349         case HTTP_METHOD_PUT: {
29350                 int fd;
29351                 chunkqueue *cq = con->request_content_queue;
29352 +               chunk *c;
29353 +               data_string *ds_range;
29354  
29355                 if (p->conf.is_readonly) {
29356                         con->http_status = 403;
29357                         return HANDLER_FINISHED;
29358                 }
29359  
29360 +               /* is a exclusive lock set on the source */
29361 +               if (!webdav_has_lock(srv, con, p, con->uri.path)) {
29362 +                       con->http_status = 423;
29363 +                       return HANDLER_FINISHED;
29364 +               }
29365 +
29366 +
29367                 assert(chunkqueue_length(cq) == (off_t)con->request.content_length);
29368  
29369 -               /* taken what we have in the request-body and write it to a file */
29370 -               if (-1 == (fd = open(con->physical.path->ptr, O_WRONLY|O_CREAT|O_TRUNC, 0600))) {
29371 -                       /* we can't open the file */
29372 -                       con->http_status = 403;
29373 +               /* RFC2616 Section 9.6 PUT requires us to send 501 on all Content-* we don't support
29374 +                * - most important Content-Range
29375 +                *
29376 +                *
29377 +                * Example: Content-Range: bytes 100-1037/1038 */
29378 +
29379 +               if (NULL != (ds_range = (data_string *)array_get_element(con->request.headers, "Content-Range"))) {
29380 +                       const char *num = ds_range->value->ptr;
29381 +                       off_t offset;
29382 +                       char *err = NULL;
29383 +
29384 +                       if (0 != strncmp(num, "bytes ", 6)) {
29385 +                               con->http_status = 501; /* not implemented */
29386 +
29387 +                               return HANDLER_FINISHED;
29388 +                       }
29389 +
29390 +                       /* we only support <num>- ... */
29391 +
29392 +                       num += 6;
29393 +
29394 +                       /* skip WS */
29395 +                       while (*num == ' ' || *num == '\t') num++;
29396 +
29397 +                       if (*num == '\0') {
29398 +                               con->http_status = 501; /* not implemented */
29399 +
29400 +                               return HANDLER_FINISHED;
29401 +                       }
29402 +
29403 +                       offset = strtoll(num, &err, 10);
29404 +
29405 +                       if (*err != '-' || offset < 0) {
29406 +                               con->http_status = 501; /* not implemented */
29407 +
29408 +                               return HANDLER_FINISHED;
29409 +                       }
29410 +
29411 +                       if (-1 == (fd = open(con->physical.path->ptr, O_WRONLY, 0600))) {
29412 +                               switch (errno) {
29413 +                               case ENOENT:
29414 +                                       con->http_status = 404; /* not found */
29415 +                                       break;
29416 +                               default:
29417 +                                       con->http_status = 403; /* not found */
29418 +                                       break;
29419 +                               }
29420 +                               return HANDLER_FINISHED;
29421 +                       }
29422 +
29423 +                       if (-1 == lseek(fd, offset, SEEK_SET)) {
29424 +                               con->http_status = 501; /* not implemented */
29425 +
29426 +                               close(fd);
29427 +
29428 +                               return HANDLER_FINISHED;
29429 +                       }
29430 +                       con->http_status = 200; /* modified */
29431                 } else {
29432 -                       chunk *c;
29433 +                       /* take what we have in the request-body and write it to a file */
29434  
29435 -                       con->http_status = 201; /* created */
29436 -                       con->file_finished = 1;
29437 +                       /* if the file doesn't exist, create it */
29438 +                       if (-1 == (fd = open(con->physical.path->ptr, O_WRONLY|O_TRUNC, 0600))) {
29439 +                               if (errno == ENOENT &&
29440 +                                   -1 == (fd = open(con->physical.path->ptr, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0600))) {
29441 +                                       /* we can't open the file */
29442 +                                       con->http_status = 403;
29443  
29444 -                       for (c = cq->first; c; c = cq->first) {
29445 -                               int r = 0; 
29446 +                                       return HANDLER_FINISHED;
29447 +                               } else {
29448 +                                       con->http_status = 201; /* created */
29449 +                               }
29450 +                       } else {
29451 +                               con->http_status = 200; /* modified */
29452 +                       }
29453 +               }
29454  
29455 -                               /* copy all chunks */
29456 -                               switch(c->type) {
29457 -                               case FILE_CHUNK:
29458 +               con->file_finished = 1;
29459  
29460 -                                       if (c->file.mmap.start == MAP_FAILED) {
29461 -                                               if (-1 == c->file.fd &&  /* open the file if not already open */
29462 -                                                   -1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) {
29463 -                                                       log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
29464 -                                       
29465 -                                                       return -1;
29466 -                                               }
29467 -                               
29468 -                                               if (MAP_FAILED == (c->file.mmap.start = mmap(0, c->file.length, PROT_READ, MAP_SHARED, c->file.fd, 0))) {
29469 -                                                       log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed: ", 
29470 -                                                                       strerror(errno), c->file.name,  c->file.fd);
29471 +               for (c = cq->first; c; c = cq->first) {
29472 +                       int r = 0;
29473  
29474 -                                                       return -1;
29475 -                                               }
29476 +                       /* copy all chunks */
29477 +                       switch(c->type) {
29478 +                       case FILE_CHUNK:
29479  
29480 -                                               c->file.mmap.length = c->file.length;
29481 +                               if (c->file.mmap.start == MAP_FAILED) {
29482 +                                       if (-1 == c->file.fd &&  /* open the file if not already open */
29483 +                                           -1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) {
29484 +                                               log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
29485  
29486 -                                               close(c->file.fd);
29487 -                                               c->file.fd = -1;
29488 -       
29489 -                                               /* chunk_reset() or chunk_free() will cleanup for us */
29490 +                                               return -1;
29491                                         }
29492  
29493 -                                       if ((r = write(fd, c->file.mmap.start + c->offset, c->file.length - c->offset)) < 0) {
29494 -                                               switch(errno) {
29495 -                                               case ENOSPC:
29496 -                                                       con->http_status = 507;
29497 -               
29498 -                                                       break;
29499 -                                               default:
29500 -                                                       con->http_status = 403;
29501 -                                                       break;
29502 -                                               }
29503 +                                       if (MAP_FAILED == (c->file.mmap.start = mmap(0, c->file.length, PROT_READ, MAP_SHARED, c->file.fd, 0))) {
29504 +                                               log_error_write(srv, __FILE__, __LINE__, "ssbd", "mmap failed: ",
29505 +                                                               strerror(errno), c->file.name,  c->file.fd);
29506 +
29507 +                                               return -1;
29508                                         }
29509 -                                       break;
29510 -                               case MEM_CHUNK:
29511 -                                       if ((r = write(fd, c->mem->ptr + c->offset, c->mem->used - c->offset - 1)) < 0) {
29512 -                                               switch(errno) {
29513 -                                               case ENOSPC:
29514 -                                                       con->http_status = 507;
29515 -               
29516 -                                                       break;
29517 -                                               default:
29518 -                                                       con->http_status = 403;
29519 -                                                       break;
29520 -                                               }
29521 +
29522 +                                       c->file.mmap.length = c->file.length;
29523 +
29524 +                                       close(c->file.fd);
29525 +                                       c->file.fd = -1;
29526 +
29527 +                                       /* chunk_reset() or chunk_free() will cleanup for us */
29528 +                               }
29529 +
29530 +                               if ((r = write(fd, c->file.mmap.start + c->offset, c->file.length - c->offset)) < 0) {
29531 +                                       switch(errno) {
29532 +                                       case ENOSPC:
29533 +                                               con->http_status = 507;
29534 +
29535 +                                               break;
29536 +                                       default:
29537 +                                               con->http_status = 403;
29538 +                                               break;
29539                                         }
29540 -                                       break;
29541 -                               case UNUSED_CHUNK:
29542 -                                       break;
29543                                 }
29544 +                               break;
29545 +                       case MEM_CHUNK:
29546 +                               if ((r = write(fd, c->mem->ptr + c->offset, c->mem->used - c->offset - 1)) < 0) {
29547 +                                       switch(errno) {
29548 +                                       case ENOSPC:
29549 +                                               con->http_status = 507;
29550  
29551 -                               if (r > 0) {
29552 -                                       c->offset += r;
29553 -                                       cq->bytes_out += r;
29554 -                               } else {
29555 -                                       break;
29556 +                                               break;
29557 +                                       default:
29558 +                                               con->http_status = 403;
29559 +                                               break;
29560 +                                       }
29561                                 }
29562 -                               chunkqueue_remove_finished_chunks(cq);
29563 +                               break;
29564 +                       case UNUSED_CHUNK:
29565 +                               break;
29566                         }
29567 -                       close(fd);
29568  
29569 +                       if (r > 0) {
29570 +                               c->offset += r;
29571 +                               cq->bytes_out += r;
29572 +                       } else {
29573 +                               break;
29574 +                       }
29575 +                       chunkqueue_remove_finished_chunks(cq);
29576                 }
29577 +               close(fd);
29578 +
29579                 return HANDLER_FINISHED;
29580         }
29581 -       case HTTP_METHOD_MOVE: 
29582 +       case HTTP_METHOD_MOVE:
29583         case HTTP_METHOD_COPY: {
29584                 buffer *destination = NULL;
29585                 char *sep, *start;
29586 @@ -1475,7 +1775,15 @@
29587                         con->http_status = 403;
29588                         return HANDLER_FINISHED;
29589                 }
29590 -               
29591 +
29592 +               /* is a exclusive lock set on the source */
29593 +               if (con->request.http_method == HTTP_METHOD_MOVE) {
29594 +                       if (!webdav_has_lock(srv, con, p, con->uri.path)) {
29595 +                               con->http_status = 423;
29596 +                               return HANDLER_FINISHED;
29597 +                       }
29598 +               }
29599 +
29600                 if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Destination"))) {
29601                         destination = ds->value;
29602                 } else {
29603 @@ -1549,10 +1857,10 @@
29604                 }
29605  
29606                 buffer_copy_string_buffer(p->physical.path, p->physical.doc_root);
29607 -               BUFFER_APPEND_SLASH(p->physical.path);
29608 +               PATHNAME_APPEND_SLASH(p->physical.path);
29609                 buffer_copy_string_buffer(p->physical.basedir, p->physical.path);
29610  
29611 -               /* don't add a second / */ 
29612 +               /* don't add a second / */
29613                 if (p->physical.rel_path->ptr[0] == '/') {
29614                         buffer_append_string_len(p->physical.path, p->physical.rel_path->ptr + 1, p->physical.rel_path->used - 2);
29615                 } else {
29616 @@ -1613,6 +1921,12 @@
29617                         /* it is just a file, good */
29618                         int r;
29619  
29620 +                       /* does the client have a lock for this connection ? */
29621 +                       if (!webdav_has_lock(srv, con, p, p->uri.path)) {
29622 +                               con->http_status = 423;
29623 +                               return HANDLER_FINISHED;
29624 +                       }
29625 +
29626                         /* destination exists */
29627                         if (0 == (r = stat(p->physical.path->ptr, &st))) {
29628                                 if (S_ISDIR(st.st_mode)) {
29629 @@ -1636,7 +1950,7 @@
29630                                         return HANDLER_FINISHED;
29631                                 }
29632                         } else if (overwrite == 0) {
29633 -                               /* destination exists, but overwrite is not set */ 
29634 +                               /* destination exists, but overwrite is not set */
29635                                 con->http_status = 412;
29636                                 return HANDLER_FINISHED;
29637                         } else {
29638 @@ -1655,16 +1969,16 @@
29639                                                 sqlite3_reset(stmt);
29640  
29641                                                 /* bind the values to the insert */
29642 -                                               sqlite3_bind_text(stmt, 1, 
29643 -                                                                 p->uri.path->ptr, 
29644 +                                               sqlite3_bind_text(stmt, 1,
29645 +                                                                 p->uri.path->ptr,
29646                                                                   p->uri.path->used - 1,
29647                                                                   SQLITE_TRANSIENT);
29648  
29649 -                                               sqlite3_bind_text(stmt, 2, 
29650 -                                                                 con->uri.path->ptr, 
29651 +                                               sqlite3_bind_text(stmt, 2,
29652 +                                                                 con->uri.path->ptr,
29653                                                                   con->uri.path->used - 1,
29654                                                                   SQLITE_TRANSIENT);
29655 -                                               
29656 +
29657                                                 if (SQLITE_DONE != sqlite3_step(stmt)) {
29658                                                         log_error_write(srv, __FILE__, __LINE__, "ss", "sql-move failed:", sqlite3_errmsg(p->conf.sql));
29659                                                 }
29660 @@ -1691,12 +2005,17 @@
29661  
29662                 return HANDLER_FINISHED;
29663         }
29664 -       case HTTP_METHOD_PROPPATCH: {
29665 +       case HTTP_METHOD_PROPPATCH:
29666                 if (p->conf.is_readonly) {
29667                         con->http_status = 403;
29668                         return HANDLER_FINISHED;
29669                 }
29670  
29671 +               if (!webdav_has_lock(srv, con, p, con->uri.path)) {
29672 +                       con->http_status = 423;
29673 +                       return HANDLER_FINISHED;
29674 +               }
29675 +
29676                 /* check if destination exists */
29677                 if (-1 == stat(con->physical.path->ptr, &st)) {
29678                         switch(errno) {
29679 @@ -1737,7 +2056,7 @@
29680  
29681                                                         sqlite3_stmt *stmt;
29682  
29683 -                                                       stmt = (0 == xmlStrcmp(cmd->name, BAD_CAST "remove")) ? 
29684 +                                                       stmt = (0 == xmlStrcmp(cmd->name, BAD_CAST "remove")) ?
29685                                                                 p->conf.stmt_delete_prop : p->conf.stmt_update_prop;
29686  
29687                                                         for (props = cmd->children; props; props = props->next) {
29688 @@ -1762,34 +2081,35 @@
29689  
29690                                                                         /* bind the values to the insert */
29691  
29692 -                                                                       sqlite3_bind_text(stmt, 1, 
29693 -                                                                                         con->uri.path->ptr, 
29694 +                                                                       sqlite3_bind_text(stmt, 1,
29695 +                                                                                         con->uri.path->ptr,
29696                                                                                           con->uri.path->used - 1,
29697                                                                                           SQLITE_TRANSIENT);
29698 -                                                                       sqlite3_bind_text(stmt, 2, 
29699 +                                                                       sqlite3_bind_text(stmt, 2,
29700                                                                                           (char *)prop->name,
29701                                                                                           strlen((char *)prop->name),
29702                                                                                           SQLITE_TRANSIENT);
29703                                                                         if (prop->ns) {
29704 -                                                                               sqlite3_bind_text(stmt, 3, 
29705 +                                                                               sqlite3_bind_text(stmt, 3,
29706                                                                                                   (char *)prop->ns->href,
29707                                                                                                   strlen((char *)prop->ns->href),
29708                                                                                                   SQLITE_TRANSIENT);
29709                                                                         } else {
29710 -                                                                               sqlite3_bind_text(stmt, 3, 
29711 +                                                                               sqlite3_bind_text(stmt, 3,
29712                                                                                                   "",
29713                                                                                                   0,
29714                                                                                                   SQLITE_TRANSIENT);
29715                                                                         }
29716                                                                         if (stmt == p->conf.stmt_update_prop) {
29717 -                                                                               sqlite3_bind_text(stmt, 4, 
29718 +                                                                               sqlite3_bind_text(stmt, 4,
29719                                                                                           (char *)xmlNodeGetContent(prop),
29720                                                                                           strlen((char *)xmlNodeGetContent(prop)),
29721                                                                                           SQLITE_TRANSIENT);
29722                                                                         }
29723 -                                                               
29724 +
29725                                                                         if (SQLITE_DONE != (r = sqlite3_step(stmt))) {
29726 -                                                                               log_error_write(srv, __FILE__, __LINE__, "ss", "sql-set failed:", sqlite3_errmsg(p->conf.sql));
29727 +                                                                               log_error_write(srv, __FILE__, __LINE__, "ss",
29728 +                                                                                               "sql-set failed:", sqlite3_errmsg(p->conf.sql));
29729                                                                         }
29730                                                                 }
29731                                                         }
29732 @@ -1804,7 +2124,7 @@
29733  
29734                                                         goto propmatch_cleanup;
29735                                                 }
29736 -       
29737 +
29738                                                 con->http_status = 400;
29739                                         } else {
29740                                                 if (SQLITE_OK != sqlite3_exec(p->conf.sql, "COMMIT", NULL, NULL, &err)) {
29741 @@ -1821,6 +2141,7 @@
29742                                 }
29743  
29744  propmatch_cleanup:
29745 +
29746                                 xmlFreeDoc(xml);
29747                         } else {
29748                                 con->http_status = 400;
29749 @@ -1830,11 +2151,307 @@
29750  #endif
29751                 con->http_status = 501;
29752                 return HANDLER_FINISHED;
29753 -       }
29754 +       case HTTP_METHOD_LOCK:
29755 +               /**
29756 +                * a mac wants to write
29757 +                *
29758 +                * LOCK /dav/expire.txt HTTP/1.1\r\n
29759 +                * User-Agent: WebDAVFS/1.3 (01308000) Darwin/8.1.0 (Power Macintosh)\r\n
29760 +                * Accept: * / *\r\n
29761 +                * Depth: 0\r\n
29762 +                * Timeout: Second-600\r\n
29763 +                * Content-Type: text/xml; charset=\"utf-8\"\r\n
29764 +                * Content-Length: 229\r\n
29765 +                * Connection: keep-alive\r\n
29766 +                * Host: 192.168.178.23:1025\r\n
29767 +                * \r\n
29768 +                * <?xml version=\"1.0\" encoding=\"utf-8\"?>\n
29769 +                * <D:lockinfo xmlns:D=\"DAV:\">\n
29770 +                *  <D:lockscope><D:exclusive/></D:lockscope>\n
29771 +                *  <D:locktype><D:write/></D:locktype>\n
29772 +                *  <D:owner>\n
29773 +                *   <D:href>http://www.apple.com/webdav_fs/</D:href>\n
29774 +                *  </D:owner>\n
29775 +                * </D:lockinfo>\n
29776 +                */
29777 +
29778 +               if (depth != 0 && depth != -1) {
29779 +                       con->http_status = 400;
29780 +
29781 +                       return HANDLER_FINISHED;
29782 +               }
29783 +
29784 +#ifdef USE_LOCKS
29785 +               if (con->request.content_length) {
29786 +                       xmlDocPtr xml;
29787 +                       buffer *hdr_if = NULL;
29788 +
29789 +                       if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "If"))) {
29790 +                               hdr_if = ds->value;
29791 +                       }
29792 +
29793 +                       /* we don't support Depth: Infinity on locks */
29794 +                       if (hdr_if == NULL && depth == -1) {
29795 +                               con->http_status = 409; /* Conflict */
29796 +
29797 +                               return HANDLER_FINISHED;
29798 +                       }
29799 +
29800 +                       if (1 == webdav_parse_chunkqueue(srv, con, p, con->request_content_queue, &xml)) {
29801 +                               xmlNode *rootnode = xmlDocGetRootElement(xml);
29802 +
29803 +                               assert(rootnode);
29804 +
29805 +                               if (0 == xmlStrcmp(rootnode->name, BAD_CAST "lockinfo")) {
29806 +                                       xmlNode *lockinfo;
29807 +                                       const xmlChar *lockscope = NULL, *locktype = NULL, *owner = NULL;
29808 +
29809 +                                       for (lockinfo = rootnode->children; lockinfo; lockinfo = lockinfo->next) {
29810 +                                               if (0 == xmlStrcmp(lockinfo->name, BAD_CAST "lockscope")) {
29811 +                                                       xmlNode *value;
29812 +                                                       for (value = lockinfo->children; value; value = value->next) {
29813 +                                                               if ((0 == xmlStrcmp(value->name, BAD_CAST "exclusive")) ||
29814 +                                                                   (0 == xmlStrcmp(value->name, BAD_CAST "shared"))) {
29815 +                                                                       lockscope = value->name;
29816 +                                                               } else {
29817 +                                                                       con->http_status = 400;
29818 +
29819 +                                                                       xmlFreeDoc(xml);
29820 +                                                                       return HANDLER_FINISHED;
29821 +                                                               }
29822 +                                                       }
29823 +                                               } else if (0 == xmlStrcmp(lockinfo->name, BAD_CAST "locktype")) {
29824 +                                                       xmlNode *value;
29825 +                                                       for (value = lockinfo->children; value; value = value->next) {
29826 +                                                               if ((0 == xmlStrcmp(value->name, BAD_CAST "write"))) {
29827 +                                                                       locktype = value->name;
29828 +                                                               } else {
29829 +                                                                       con->http_status = 400;
29830 +
29831 +                                                                       xmlFreeDoc(xml);
29832 +                                                                       return HANDLER_FINISHED;
29833 +                                                               }
29834 +                                                       }
29835 +
29836 +                                               } else if (0 == xmlStrcmp(lockinfo->name, BAD_CAST "owner")) {
29837 +                                               }
29838 +                                       }
29839 +
29840 +                                       if (lockscope && locktype) {
29841 +                                               sqlite3_stmt *stmt = p->conf.stmt_read_lock_by_uri;
29842 +
29843 +                                               /* is this resourse already locked ? */
29844 +
29845 +                                               /* SELECT locktoken, resource, lockscope, locktype, owner, depth, timeout
29846 +                                                *   FROM locks
29847 +                                                *  WHERE resource = ? */
29848 +
29849 +                                               if (stmt) {
29850 +
29851 +                                                       sqlite3_reset(stmt);
29852 +
29853 +                                                       sqlite3_bind_text(stmt, 1,
29854 +                                                                         p->uri.path->ptr,
29855 +                                                                         p->uri.path->used - 1,
29856 +                                                                         SQLITE_TRANSIENT);
29857 +
29858 +                                                       /* it is the PK */
29859 +                                                       while (SQLITE_ROW == sqlite3_step(stmt)) {
29860 +                                                               /* we found a lock
29861 +                                                                * 1. is it compatible ?
29862 +                                                                * 2. is it ours */
29863 +                                                               char *sql_lockscope = (char *)sqlite3_column_text(stmt, 2);
29864 +
29865 +                                                               if (strcmp(sql_lockscope, "exclusive")) {
29866 +                                                                       con->http_status = 423;
29867 +                                                               } else if (0 == xmlStrcmp(lockscope, BAD_CAST "exclusive")) {
29868 +                                                                       /* resourse is locked with a shared lock
29869 +                                                                        * client wants exclusive */
29870 +                                                                       con->http_status = 423;
29871 +                                                               }
29872 +                                                       }
29873 +                                                       if (con->http_status == 423) {
29874 +                                                               xmlFreeDoc(xml);
29875 +                                                               return HANDLER_FINISHED;
29876 +                                                       }
29877 +                                               }
29878 +
29879 +                                               stmt = p->conf.stmt_create_lock;
29880 +                                               if (stmt) {
29881 +                                                       /* create a lock-token */
29882 +                                                       uuid_t id;
29883 +                                                       char uuid[37] /* 36 + \0 */;
29884 +
29885 +                                                       uuid_generate(id);
29886 +                                                       uuid_unparse(id, uuid);
29887 +
29888 +                                                       buffer_copy_string(p->tmp_buf, "opaquelocktoken:");
29889 +                                                       buffer_append_string(p->tmp_buf, uuid);
29890 +
29891 +                                                       /* "CREATE TABLE locks ("
29892 +                                                        * "  locktoken TEXT NOT NULL,"
29893 +                                                        * "  resource TEXT NOT NULL,"
29894 +                                                        * "  lockscope TEXT NOT NULL,"
29895 +                                                        * "  locktype TEXT NOT NULL,"
29896 +                                                        * "  owner TEXT NOT NULL,"
29897 +                                                        * "  depth INT NOT NULL,"
29898 +                                                        */
29899 +
29900 +                                                       sqlite3_reset(stmt);
29901 +
29902 +                                                       sqlite3_bind_text(stmt, 1,
29903 +                                                                         CONST_BUF_LEN(p->tmp_buf),
29904 +                                                                         SQLITE_TRANSIENT);
29905 +
29906 +                                                       sqlite3_bind_text(stmt, 2,
29907 +                                                                         CONST_BUF_LEN(con->uri.path),
29908 +                                                                         SQLITE_TRANSIENT);
29909 +
29910 +                                                       sqlite3_bind_text(stmt, 3,
29911 +                                                                         lockscope,
29912 +                                                                         xmlStrlen(lockscope),
29913 +                                                                         SQLITE_TRANSIENT);
29914 +
29915 +                                                       sqlite3_bind_text(stmt, 4,
29916 +                                                                         locktype,
29917 +                                                                         xmlStrlen(locktype),
29918 +                                                                         SQLITE_TRANSIENT);
29919 +
29920 +                                                       /* owner */
29921 +                                                       sqlite3_bind_text(stmt, 5,
29922 +                                                                         "",
29923 +                                                                         0,
29924 +                                                                         SQLITE_TRANSIENT);
29925 +
29926 +                                                       /* depth */
29927 +                                                       sqlite3_bind_int(stmt, 6,
29928 +                                                                        depth);
29929 +
29930 +
29931 +                                                       if (SQLITE_DONE != sqlite3_step(stmt)) {
29932 +                                                               log_error_write(srv, __FILE__, __LINE__, "ss",
29933 +                                                                               "create lock:", sqlite3_errmsg(p->conf.sql));
29934 +                                                       }
29935 +
29936 +                                                       /* looks like we survived */
29937 +                                                       webdav_lockdiscovery(srv, con, p->tmp_buf, lockscope, locktype, depth);
29938 +
29939 +                                                       con->http_status = 201;
29940 +                                                       con->file_finished = 1;
29941 +                                               }
29942 +                                       }
29943 +                               }
29944 +
29945 +                               xmlFreeDoc(xml);
29946 +                               return HANDLER_FINISHED;
29947 +                       } else {
29948 +                               con->http_status = 400;
29949 +                               return HANDLER_FINISHED;
29950 +                       }
29951 +               } else {
29952 +
29953 +                       if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "If"))) {
29954 +                               buffer *locktoken = ds->value;
29955 +                               sqlite3_stmt *stmt = p->conf.stmt_refresh_lock;
29956 +
29957 +                               /* remove the < > around the token */
29958 +                               if (locktoken->used < 6) {
29959 +                                       con->http_status = 400;
29960 +
29961 +                                       return HANDLER_FINISHED;
29962 +                               }
29963 +
29964 +                               buffer_copy_string_len(p->tmp_buf, locktoken->ptr + 2, locktoken->used - 5);
29965 +
29966 +                               sqlite3_reset(stmt);
29967 +
29968 +                               sqlite3_bind_text(stmt, 1,
29969 +                                         CONST_BUF_LEN(p->tmp_buf),
29970 +                                         SQLITE_TRANSIENT);
29971 +
29972 +                               if (SQLITE_DONE != sqlite3_step(stmt)) {
29973 +                                       log_error_write(srv, __FILE__, __LINE__, "ss",
29974 +                                               "refresh lock:", sqlite3_errmsg(p->conf.sql));
29975 +                               }
29976 +
29977 +                               webdav_lockdiscovery(srv, con, p->tmp_buf, "exclusive", "write", 0);
29978 +
29979 +                               con->http_status = 200;
29980 +                               con->file_finished = 1;
29981 +                               return HANDLER_FINISHED;
29982 +                       } else {
29983 +                               /* we need a lock-token to refresh */
29984 +                               con->http_status = 400;
29985 +
29986 +                               return HANDLER_FINISHED;
29987 +                       }
29988 +               }
29989 +               break;
29990 +#else
29991 +               con->http_status = 501;
29992 +               return HANDLER_FINISHED;
29993 +#endif
29994 +       case HTTP_METHOD_UNLOCK:
29995 +#ifdef USE_LOCKS
29996 +               if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Lock-Token"))) {
29997 +                       buffer *locktoken = ds->value;
29998 +                       sqlite3_stmt *stmt = p->conf.stmt_remove_lock;
29999 +
30000 +                       /* remove the < > around the token */
30001 +                       if (locktoken->used < 4) {
30002 +                               con->http_status = 400;
30003 +
30004 +                               return HANDLER_FINISHED;
30005 +                       }
30006 +
30007 +                       /**
30008 +                        * FIXME:
30009 +                        *
30010 +                        * if the resourse is locked:
30011 +                        * - by us: unlock
30012 +                        * - by someone else: 401
30013 +                        * if the resource is not locked:
30014 +                        * - 412
30015 +                        *  */
30016 +
30017 +                       buffer_copy_string_len(p->tmp_buf, locktoken->ptr + 1, locktoken->used - 3);
30018 +
30019 +                       sqlite3_reset(stmt);
30020 +
30021 +                       sqlite3_bind_text(stmt, 1,
30022 +                                 CONST_BUF_LEN(p->tmp_buf),
30023 +                                 SQLITE_TRANSIENT);
30024 +
30025 +                       sqlite3_bind_text(stmt, 2,
30026 +                                 CONST_BUF_LEN(con->uri.path),
30027 +                                 SQLITE_TRANSIENT);
30028 +
30029 +                       if (SQLITE_DONE != sqlite3_step(stmt)) {
30030 +                               log_error_write(srv, __FILE__, __LINE__, "ss",
30031 +                                       "remove lock:", sqlite3_errmsg(p->conf.sql));
30032 +                       }
30033 +
30034 +                       if (0 == sqlite3_changes(p->conf.sql)) {
30035 +                               con->http_status = 401;
30036 +                       } else {
30037 +                               con->http_status = 204;
30038 +                       }
30039 +                       return HANDLER_FINISHED;
30040 +               } else {
30041 +                       /* we need a lock-token to unlock */
30042 +                       con->http_status = 400;
30043 +
30044 +                       return HANDLER_FINISHED;
30045 +               }
30046 +               break;
30047 +#else
30048 +               con->http_status = 501;
30049 +               return HANDLER_FINISHED;
30050 +#endif
30051         default:
30052                 break;
30053         }
30054 -       
30055 +
30056         /* not found */
30057         return HANDLER_GO_ON;
30058  }
30059 @@ -1845,14 +2462,14 @@
30060  int mod_webdav_plugin_init(plugin *p) {
30061         p->version     = LIGHTTPD_VERSION_ID;
30062         p->name        = buffer_init_string("webdav");
30063 -       
30064 +
30065         p->init        = mod_webdav_init;
30066         p->handle_uri_clean  = mod_webdav_uri_handler;
30067         p->handle_physical   = mod_webdav_subrequest_handler;
30068         p->set_defaults  = mod_webdav_set_defaults;
30069         p->cleanup     = mod_webdav_free;
30070 -       
30071 +
30072         p->data        = NULL;
30073 -       
30074 +
30075         return 0;
30076  }
30077
30078 Property changes on: src/mod_webdav.c
30079 ___________________________________________________________________
30080 Name: svn:eol-style
30081    + native
30082
30083 Index: src/configparser.y
30084 ===================================================================
30085 --- src/configparser.y  (.../tags/lighttpd-1.4.11)      (revision 1159)
30086 +++ src/configparser.y  (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
30087 @@ -21,52 +21,34 @@
30088      dc->parent = ctx->current;
30089      array_insert_unique(dc->parent->childs, (data_unset *)dc);
30090    }
30091 -  array_insert_unique(ctx->configs_stack, (data_unset *)ctx->current);
30092 +  buffer_ptr_append(ctx->configs_stack, (void *)ctx->current);
30093    ctx->current = dc;
30094  }
30095  
30096  static data_config *configparser_pop(config_t *ctx) {
30097    data_config *old = ctx->current;
30098 -  ctx->current = (data_config *) array_pop(ctx->configs_stack);
30099 +  ctx->current = (data_config *) buffer_ptr_pop(ctx->configs_stack);
30100    return old;
30101  }
30102  
30103  /* return a copied variable */
30104  static data_unset *configparser_get_variable(config_t *ctx, const buffer *key) {
30105 -  if (strncmp(key->ptr, "env.", sizeof("env.") - 1) == 0) {
30106 -    char *env;
30107 +  data_unset *du;
30108 +  data_config *dc;
30109  
30110 -    if (NULL != (env = getenv(key->ptr + 4))) {
30111 -      data_string *ds;
30112 -      ds = data_string_init();
30113 -      buffer_append_string(ds->value, env);
30114 -      return (data_unset *)ds;
30115 -    }
30116 -
30117 -    fprintf(stderr, "Undefined env variable: %s\n", key->ptr + 4);
30118 -    ctx->ok = 0;
30119 -
30120 -    return NULL;
30121 -  } else {
30122 -    data_unset *du;
30123 -    data_config *dc;
30124 -
30125  #if 0
30126 -    fprintf(stderr, "get var %s\n", key->ptr);
30127 +  fprintf(stderr, "get var %s\n", key->ptr);
30128  #endif
30129 -    for (dc = ctx->current; dc; dc = dc->parent) {
30130 +  for (dc = ctx->current; dc; dc = dc->parent) {
30131  #if 0
30132 -      fprintf(stderr, "get var on block: %s\n", dc->key->ptr);
30133 -      array_print(dc->value, 0);
30134 +    fprintf(stderr, "get var on block: %s\n", dc->key->ptr);
30135 +    array_print(dc->value, 0);
30136  #endif
30137 -      if (NULL != (du = array_get_element(dc->value, key->ptr))) {
30138 -        return du->copy(du);
30139 -      }
30140 +    if (NULL != (du = array_get_element(dc->value, key->ptr))) {
30141 +      return du->copy(du);
30142      }
30143 -    fprintf(stderr, "Undefined config variable: %s\n", key->ptr);
30144 -    ctx->ok = 0;
30145 -    return NULL;
30146    }
30147 +  return NULL;
30148  }
30149  
30150  /* op1 is to be eat/return by this function, op1->key is not cared
30151 @@ -141,6 +123,7 @@
30152  %type       aelement               {data_unset *}
30153  %type       condline               {data_config *}
30154  %type       condlines              {data_config *}
30155 +%type       global                 {data_config *}
30156  %type       aelements              {array *}
30157  %type       array                  {array *}
30158  %type       key                    {buffer *}
30159 @@ -161,7 +144,12 @@
30160  
30161  varline ::= key(A) ASSIGN expression(B). {
30162    buffer_copy_string_buffer(B->key, A);
30163 -  if (NULL == array_get_element(ctx->current->value, B->key->ptr)) {
30164 +  if (strncmp(A->ptr, "env.", sizeof("env.") - 1) == 0) {
30165 +    fprintf(stderr, "Setting env variable is not supported in conditional %d %s: %s\n",
30166 +        ctx->current->context_ndx,
30167 +        ctx->current->key->ptr, A->ptr);
30168 +    ctx->ok = 0;
30169 +  } else if (NULL == array_get_element(ctx->current->value, B->key->ptr)) {
30170      array_insert_unique(ctx->current->value, B);
30171      B = NULL;
30172    } else {
30173 @@ -180,7 +168,12 @@
30174    array *vars = ctx->current->value;
30175    data_unset *du;
30176  
30177 -  if (NULL != (du = array_get_element(vars, A->ptr))) {
30178 +  if (strncmp(A->ptr, "env.", sizeof("env.") - 1) == 0) {
30179 +    fprintf(stderr, "Appending env variable is not supported in conditional %d %s: %s\n",
30180 +        ctx->current->context_ndx,
30181 +        ctx->current->key->ptr, A->ptr);
30182 +    ctx->ok = 0;
30183 +  } else if (NULL != (du = array_get_element(vars, A->ptr))) {
30184      /* exists in current block */
30185      du = configparser_merge_data(du, B);
30186      if (NULL == du) {
30187 @@ -190,6 +183,7 @@
30188        buffer_copy_string_buffer(du->key, A);
30189        array_replace(vars, du);
30190      }
30191 +    B->free(B);
30192    } else if (NULL != (du = configparser_get_variable(ctx, A))) {
30193      du = configparser_merge_data(du, B);
30194      if (NULL == du) {
30195 @@ -199,15 +193,13 @@
30196        buffer_copy_string_buffer(du->key, A);
30197        array_insert_unique(ctx->current->value, du);
30198      }
30199 +    B->free(B);
30200    } else {
30201 -    fprintf(stderr, "Undefined config variable in conditional %d %s: %s\n", 
30202 -            ctx->current->context_ndx,
30203 -            ctx->current->key->ptr, A->ptr);
30204 -    ctx->ok = 0;
30205 +    buffer_copy_string_buffer(B->key, A);
30206 +    array_insert_unique(ctx->current->value, B);
30207    }
30208    buffer_free(A);
30209    A = NULL;
30210 -  B->free(B);
30211    B = NULL;
30212  }
30213  
30214 @@ -239,7 +231,24 @@
30215  }
30216  
30217  value(A) ::= key(B). {
30218 -  A = configparser_get_variable(ctx, B);
30219 +  if (strncmp(B->ptr, "env.", sizeof("env.") - 1) == 0) {
30220 +    char *env;
30221 +
30222 +    if (NULL != (env = getenv(B->ptr + 4))) {
30223 +      data_string *ds;
30224 +      ds = data_string_init();
30225 +      buffer_append_string(ds->value, env);
30226 +      A = (data_unset *)ds;
30227 +    }
30228 +    else {
30229 +      A = NULL;
30230 +      fprintf(stderr, "Undefined env variable: %s\n", B->ptr + 4);
30231 +      ctx->ok = 0;
30232 +    }
30233 +  } else if (NULL == (A = configparser_get_variable(ctx, B))) {
30234 +    fprintf(stderr, "Undefined config variable: %s\n", B->ptr);
30235 +    ctx->ok = 0;
30236 +  }
30237    if (!A) {
30238      /* make a dummy so it won't crash */
30239      A = (data_unset *)data_string_init();
30240 @@ -267,6 +276,9 @@
30241    ((data_array *)(A))->value = B;
30242    B = NULL;
30243  }
30244 +array(A) ::= LPARAN RPARAN. {
30245 +  A = array_init();
30246 +}
30247  array(A) ::= LPARAN aelements(B) RPARAN. {
30248    A = B;
30249    B = NULL;
30250
30251 Property changes on: src/configparser.y
30252 ___________________________________________________________________
30253 Name: svn:eol-style
30254    + native
30255
30256 Index: src/http_resp_parser.y
30257 ===================================================================
30258 --- src/http_resp_parser.y      (.../tags/lighttpd-1.4.11)      (revision 0)
30259 +++ src/http_resp_parser.y      (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
30260 @@ -0,0 +1,124 @@
30261 +%token_prefix TK_
30262 +%token_type {buffer *}
30263 +%extra_argument {http_resp_ctx_t *ctx}
30264 +%name http_resp_parser
30265 +
30266 +%include {
30267 +#include <assert.h>
30268 +#include <string.h>
30269 +#include "http_resp.h"
30270 +#include "keyvalue.h"
30271 +#include "array.h"
30272 +}
30273 +
30274 +%parse_failure {
30275 +  ctx->ok = 0;
30276 +}
30277 +
30278 +%type protocol { int }
30279 +%type response_hdr { http_resp * }
30280 +%type number { int }
30281 +%type headers { array * }
30282 +%type header { data_string * }
30283 +%token_destructor { buffer_free($$); }
30284 +
30285 +/* just headers + Status: ... */
30286 +response_hdr ::= headers(HDR) CRLF . {
30287 +    http_resp *resp = ctx->resp;
30288 +    data_string *ds;
30289
30290 +    resp->protocol = HTTP_VERSION_UNSET;
30291 +
30292 +    buffer_copy_string(resp->reason, ""); /* no reason */
30293 +    array_free(resp->headers);
30294 +    resp->headers = HDR;
30295 +
30296 +    if (NULL == (ds = (data_string *)array_get_element(HDR, "Status"))) { 
30297 +        resp->status = 0;
30298 +    } else {
30299 +        char *err;
30300 +        resp->status = strtol(ds->value->ptr, &err, 10);
30301 +    
30302 +        if (*err != '\0') {
30303 +            buffer_copy_string(ctx->errmsg, "expected a number: ");
30304 +            buffer_append_string_buffer(ctx->errmsg, ds->value);
30305 +        
30306 +            ctx->ok = 0;
30307 +        }
30308 +
30309 +    }
30310 +
30311 +    HDR = NULL;
30312 +}
30313 +/* HTTP/1.0 <status> ... */
30314 +response_hdr ::= protocol(B) number(C) reason(D) CRLF headers(HDR) CRLF . {
30315 +    http_resp *resp = ctx->resp;
30316 +    
30317 +    resp->status = C;
30318 +    resp->protocol = B;
30319 +    buffer_copy_string_buffer(resp->reason, D);
30320 +    
30321 +    array_free(resp->headers);
30322 +    
30323 +    resp->headers = HDR;
30324 +    
30325 +    HDR = NULL;
30326 +}
30327 +
30328 +protocol(A) ::= STRING(B). {
30329 +    if (buffer_is_equal_string(B, CONST_STR_LEN("HTTP/1.0"))) {
30330 +        A = HTTP_VERSION_1_0;
30331 +    } else if (buffer_is_equal_string(B, CONST_STR_LEN("HTTP/1.1"))) {
30332 +        A = HTTP_VERSION_1_1;
30333 +    } else {
30334 +        buffer_copy_string(ctx->errmsg, "unknown protocol: ");
30335 +        buffer_append_string_buffer(ctx->errmsg, B);
30336 +        
30337 +        ctx->ok = 0;
30338 +    }
30339 +}
30340 +
30341 +number(A) ::= STRING(B). {
30342 +    char *err;
30343 +    A = strtol(B->ptr, &err, 10);
30344 +    
30345 +    if (*err != '\0') {
30346 +        buffer_copy_string(ctx->errmsg, "expected a number: ");
30347 +        buffer_append_string_buffer(ctx->errmsg, B);
30348 +        
30349 +        ctx->ok = 0;
30350 +    }
30351 +}
30352 +
30353 +reason(A) ::= STRING(B). {
30354 +    buffer_copy_string_buffer(A, B);
30355 +}
30356 +
30357 +reason(A) ::= reason(C) STRING(B). {
30358 +    A = C;
30359 +    
30360 +    buffer_append_string(A, " ");
30361 +    buffer_append_string_buffer(A, B);
30362 +    
30363 +    C = NULL;
30364 +}
30365 +
30366 +headers(HDRS) ::= headers(SRC) header(HDR). {
30367 +    HDRS = SRC;
30368 +    
30369 +    array_insert_unique(HDRS, (data_unset *)HDR);
30370 +    
30371 +    SRC = NULL;
30372 +}
30373 +
30374 +headers(HDRS) ::= header(HDR). {
30375 +    HDRS = array_init();
30376 +
30377 +    array_insert_unique(HDRS, (data_unset *)HDR);
30378 +}
30379 +header(HDR) ::= STRING(A) COLON STRING(B) CRLF. {
30380 +    HDR = data_string_init();
30381 +    
30382 +    buffer_copy_string_buffer(HDR->key, A);
30383 +    buffer_copy_string_buffer(HDR->value, B);    
30384 +}
30385
30386 Property changes on: src/http_resp_parser.y
30387 ___________________________________________________________________
30388 Name: svn:eol-style
30389    + native
30390
30391
30392 Property changes on: src/crc32.c
30393 ___________________________________________________________________
30394 Name: svn:eol-style
30395    + native
30396
30397 Index: src/crc32.h
30398 ===================================================================
30399 --- src/crc32.h (.../tags/lighttpd-1.4.11)      (revision 1159)
30400 +++ src/crc32.h (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
30401 @@ -6,6 +6,7 @@
30402  #endif
30403  
30404  #include <sys/types.h>
30405 +#include <stdlib.h>
30406  
30407  #if defined HAVE_STDINT_H
30408  #include <stdint.h>
30409 @@ -13,6 +14,10 @@
30410  #include <inttypes.h>
30411  #endif
30412  
30413 +#ifdef _WIN32
30414 +#define uint32_t unsigned __int32
30415 +#endif
30416 +
30417  uint32_t generate_crc32c(char *string, size_t length);
30418  
30419  #endif
30420
30421 Property changes on: src/crc32.h
30422 ___________________________________________________________________
30423 Name: svn:eol-style
30424    + native
30425
30426 Index: src/mod_status.c
30427 ===================================================================
30428 --- src/mod_status.c    (.../tags/lighttpd-1.4.11)      (revision 1159)
30429 +++ src/mod_status.c    (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
30430 @@ -4,7 +4,6 @@
30431  #include <fcntl.h>
30432  #include <stdlib.h>
30433  #include <string.h>
30434 -#include <unistd.h>
30435  #include <errno.h>
30436  #include <time.h>
30437  #include <stdio.h>
30438 @@ -29,114 +28,114 @@
30439  
30440  typedef struct {
30441         PLUGIN_DATA;
30442 -       
30443 +
30444         double traffic_out;
30445         double requests;
30446 -       
30447 +
30448         double mod_5s_traffic_out[5];
30449         double mod_5s_requests[5];
30450         size_t mod_5s_ndx;
30451 -       
30452 +
30453         double rel_traffic_out;
30454         double rel_requests;
30455 -       
30456 +
30457         double abs_traffic_out;
30458         double abs_requests;
30459 -       
30460 +
30461         double bytes_written;
30462 -       
30463 +
30464         buffer *module_list;
30465 -       
30466 +
30467         plugin_config **config_storage;
30468 -       
30469 -       plugin_config conf; 
30470 +
30471 +       plugin_config conf;
30472  } plugin_data;
30473  
30474  INIT_FUNC(mod_status_init) {
30475         plugin_data *p;
30476         size_t i;
30477 -       
30478 +
30479         p = calloc(1, sizeof(*p));
30480 -       
30481 +
30482         p->traffic_out = p->requests = 0;
30483         p->rel_traffic_out = p->rel_requests = 0;
30484         p->abs_traffic_out = p->abs_requests = 0;
30485         p->bytes_written = 0;
30486         p->module_list = buffer_init();
30487 -       
30488 +
30489         for (i = 0; i < 5; i++) {
30490                 p->mod_5s_traffic_out[i] = p->mod_5s_requests[i] = 0;
30491         }
30492 -       
30493 +
30494         return p;
30495  }
30496  
30497  FREE_FUNC(mod_status_free) {
30498         plugin_data *p = p_d;
30499 -       
30500 +
30501         UNUSED(srv);
30502  
30503         if (!p) return HANDLER_GO_ON;
30504 -       
30505 +
30506         buffer_free(p->module_list);
30507 -       
30508 +
30509         if (p->config_storage) {
30510                 size_t i;
30511                 for (i = 0; i < srv->config_context->used; i++) {
30512                         plugin_config *s = p->config_storage[i];
30513 -                       
30514 +
30515                         buffer_free(s->status_url);
30516                         buffer_free(s->statistics_url);
30517                         buffer_free(s->config_url);
30518 -                       
30519 +
30520                         free(s);
30521                 }
30522                 free(p->config_storage);
30523         }
30524 -       
30525 -       
30526 +
30527 +
30528         free(p);
30529 -       
30530 +
30531         return HANDLER_GO_ON;
30532  }
30533  
30534  SETDEFAULTS_FUNC(mod_status_set_defaults) {
30535         plugin_data *p = p_d;
30536         size_t i;
30537 -       
30538 -       config_values_t cv[] = { 
30539 +
30540 +       config_values_t cv[] = {
30541                 { "status.status-url",           NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
30542                 { "status.config-url",           NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
30543                 { "status.enable-sort",          NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },
30544                 { "status.statistics-url",       NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
30545                 { NULL,                          NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
30546         };
30547 -       
30548 +
30549         if (!p) return HANDLER_ERROR;
30550 -       
30551 +
30552         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
30553 -       
30554 +
30555         for (i = 0; i < srv->config_context->used; i++) {
30556                 plugin_config *s;
30557 -               
30558 +
30559                 s = calloc(1, sizeof(plugin_config));
30560                 s->config_url    = buffer_init();
30561                 s->status_url    = buffer_init();
30562                 s->sort          = 1;
30563                 s->statistics_url    = buffer_init();
30564 -               
30565 +
30566                 cv[0].destination = s->status_url;
30567                 cv[1].destination = s->config_url;
30568                 cv[2].destination = &(s->sort);
30569                 cv[3].destination = s->statistics_url;
30570 -               
30571 +
30572                 p->config_storage[i] = s;
30573 -       
30574 +
30575                 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
30576                         return HANDLER_ERROR;
30577                 }
30578         }
30579 -       
30580 +
30581         return HANDLER_GO_ON;
30582  }
30583  
30584 @@ -151,7 +150,7 @@
30585         buffer_append_string(b, value);
30586         BUFFER_APPEND_STRING_CONST(b, "</td>\n");
30587         BUFFER_APPEND_STRING_CONST(b, "   </tr>\n");
30588 -       
30589 +
30590         return 0;
30591  }
30592  
30593 @@ -161,13 +160,13 @@
30594         buffer_append_string(b, key);
30595         BUFFER_APPEND_STRING_CONST(b, "</th>\n");
30596         BUFFER_APPEND_STRING_CONST(b, "   </tr>\n");
30597 -       
30598 +
30599         return 0;
30600  }
30601  
30602  static int mod_status_header_append_sort(buffer *b, void *p_d, const char* key) {
30603         plugin_data *p = p_d;
30604 -       
30605 +
30606         if (p->conf.sort) {
30607                 BUFFER_APPEND_STRING_CONST(b, "<th class=\"status\"><a href=\"#\" class=\"sortheader\" onclick=\"resort(this);return false;\">");
30608                 buffer_append_string(b, key);
30609 @@ -177,13 +176,13 @@
30610                 buffer_append_string(b, key);
30611                 BUFFER_APPEND_STRING_CONST(b, "</th>\n");
30612         }
30613 -       
30614 +
30615         return 0;
30616  }
30617  
30618  static int mod_status_get_multiplier(double *avg, char *multiplier, int size) {
30619         *multiplier = ' ';
30620 -       
30621 +
30622         if (*avg > size) { *avg /= size; *multiplier = 'k'; }
30623         if (*avg > size) { *avg /= size; *multiplier = 'M'; }
30624         if (*avg > size) { *avg /= size; *multiplier = 'G'; }
30625 @@ -202,21 +201,21 @@
30626         size_t j;
30627         double avg;
30628         char multiplier = '\0';
30629 -       char buf[32];
30630 +       char buf[128];
30631         time_t ts;
30632 -       
30633 +
30634         int days, hours, mins, seconds;
30635 -       
30636 +
30637         b = chunkqueue_get_append_buffer(con->write_queue);
30638  
30639 -       BUFFER_COPY_STRING_CONST(b, 
30640 +       BUFFER_COPY_STRING_CONST(b,
30641                                  "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
30642                                  "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
30643                                  "         \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"
30644                                  "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n"
30645                                  " <head>\n"
30646                                  "  <title>Status</title>\n");
30647 -       
30648 +
30649         BUFFER_APPEND_STRING_CONST(b,
30650                                    "  <style type=\"text/css\">\n"
30651                                    "    table.status { border: black solid thin; }\n"
30652 @@ -226,14 +225,14 @@
30653                                    "    a.sortheader { background-color: black; color: white; font-weight: bold; text-decoration: none; display: block; }\n"
30654                                    "    span.sortarrow { color: white; text-decoration: none; }\n"
30655                                    "  </style>\n");
30656 -       
30657 +
30658         if (p->conf.sort) {
30659                 BUFFER_APPEND_STRING_CONST(b,
30660                                            "<script type=\"text/javascript\">\n"
30661                                            "// <!--\n"
30662                                            "var sort_column;\n"
30663                                            "var prev_span = null;\n");
30664 -               
30665 +
30666                 BUFFER_APPEND_STRING_CONST(b,
30667                                            "function get_inner_text(el) {\n"
30668                                            " if((typeof el == 'string')||(typeof el == 'undefined'))\n"
30669 @@ -251,7 +250,7 @@
30670                                            " }\n"
30671                                            " return str;\n"
30672                                            "}\n");
30673 -               
30674 +
30675                 BUFFER_APPEND_STRING_CONST(b,
30676                                            "function sortfn(a,b) {\n"
30677                                            " var at = get_inner_text(a.cells[sort_column]);\n"
30678 @@ -266,7 +265,7 @@
30679                                            "  else return 1;\n"
30680                                            " }\n"
30681                                            "}\n");
30682 -               
30683 +
30684                 BUFFER_APPEND_STRING_CONST(b,
30685                                            "function resort(lnk) {\n"
30686                                            " var span = lnk.childNodes[1];\n"
30687 @@ -276,7 +275,7 @@
30688                                            "  rows[j-1] = table.rows[j];\n"
30689                                            " sort_column = lnk.parentNode.cellIndex;\n"
30690                                            " rows.sort(sortfn);\n");
30691 -               
30692 +
30693                 BUFFER_APPEND_STRING_CONST(b,
30694                                            " if (prev_span != null) prev_span.innerHTML = '';\n"
30695                                            " if (span.getAttribute('sortdir')=='down') {\n"
30696 @@ -294,175 +293,175 @@
30697                                            "// -->\n"
30698                                            "</script>\n");
30699         }
30700 -       
30701 -       BUFFER_APPEND_STRING_CONST(b, 
30702 +
30703 +       BUFFER_APPEND_STRING_CONST(b,
30704                                  " </head>\n"
30705                                  " <body>\n");
30706 -       
30707 -       
30708 -       
30709 +
30710 +
30711 +
30712         /* connection listing */
30713         BUFFER_APPEND_STRING_CONST(b, "<h1>Server-Status</h1>");
30714 -       
30715 -       BUFFER_APPEND_STRING_CONST(b, "<table class=\"status\">");
30716 -       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Hostname</td><td class=\"string\">");
30717 +
30718 +       BUFFER_APPEND_STRING_CONST(b, "<table class=\"status\" id=\"status\" summary=\"Server Status\">");
30719 +       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Hostname</td><td class=\"string\"><span id=\"host_addr\">");
30720         buffer_append_string_buffer(b, con->uri.authority);
30721 -       BUFFER_APPEND_STRING_CONST(b, " (");
30722 +       BUFFER_APPEND_STRING_CONST(b, "</span> (<span id=\"host_name\">");
30723         buffer_append_string_buffer(b, con->server_name);
30724 -       BUFFER_APPEND_STRING_CONST(b, ")</td></tr>\n");
30725 -       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Uptime</td><td class=\"string\">");
30726 -       
30727 +       BUFFER_APPEND_STRING_CONST(b, "</span>)</td></tr>\n");
30728 +       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Uptime</td><td class=\"string\" id=\"uptime\">");
30729 +
30730         ts = srv->cur_ts - srv->startup_ts;
30731 -       
30732 +
30733         days = ts / (60 * 60 * 24);
30734         ts %= (60 * 60 * 24);
30735 -       
30736 +
30737         hours = ts / (60 * 60);
30738         ts %= (60 * 60);
30739 -       
30740 +
30741         mins = ts / (60);
30742         ts %= (60);
30743 -       
30744 +
30745         seconds = ts;
30746 -       
30747 +
30748         if (days) {
30749                 buffer_append_long(b, days);
30750                 BUFFER_APPEND_STRING_CONST(b, " days ");
30751         }
30752 -       
30753 +
30754         if (hours) {
30755                 buffer_append_long(b, hours);
30756                 BUFFER_APPEND_STRING_CONST(b, " hours ");
30757         }
30758 -       
30759 +
30760         if (mins) {
30761                 buffer_append_long(b, mins);
30762                 BUFFER_APPEND_STRING_CONST(b, " min ");
30763         }
30764 -       
30765 +
30766         buffer_append_long(b, seconds);
30767         BUFFER_APPEND_STRING_CONST(b, " s");
30768 -       
30769 +
30770         BUFFER_APPEND_STRING_CONST(b, "</td></tr>\n");
30771         BUFFER_APPEND_STRING_CONST(b, "<tr><td>Started at</td><td class=\"string\">");
30772 -       
30773 +
30774         ts = srv->startup_ts;
30775 -       
30776 -       strftime(buf, sizeof(buf) - 1, "%Y-%m-%d %H:%M:%S", localtime(&ts));
30777 +
30778 +       strftime(buf, sizeof(buf) - 1, "<span id=\"start_date\">%Y-%m-%d</span> <span id=\"start_time\">%H:%M:%S</span>", localtime(&ts));
30779         buffer_append_string(b, buf);
30780         BUFFER_APPEND_STRING_CONST(b, "</td></tr>\n");
30781 -       
30782 -       
30783 +
30784 +
30785         BUFFER_APPEND_STRING_CONST(b, "<tr><th colspan=\"2\">absolute (since start)</th></tr>\n");
30786 -       
30787 -       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\">");
30788 +
30789 +       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\" ><span id=\"requests\">");
30790         avg = p->abs_requests;
30791  
30792         mod_status_get_multiplier(&avg, &multiplier, 1000);
30793 -       
30794 +
30795         buffer_append_long(b, avg);
30796 -       BUFFER_APPEND_STRING_CONST(b, " ");
30797 +       BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"requests_mult\">");
30798         if (multiplier) buffer_append_string_len(b, &multiplier, 1);
30799 -       BUFFER_APPEND_STRING_CONST(b, "req</td></tr>\n");
30800 -       
30801 -       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\">");
30802 +       BUFFER_APPEND_STRING_CONST(b, "</span>req</td></tr>\n");
30803 +
30804 +       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\"><span id=\"traffic\">");
30805         avg = p->abs_traffic_out;
30806  
30807         mod_status_get_multiplier(&avg, &multiplier, 1024);
30808  
30809         sprintf(buf, "%.2f", avg);
30810         buffer_append_string(b, buf);
30811 -       BUFFER_APPEND_STRING_CONST(b, " ");
30812 +       BUFFER_APPEND_STRING_CONST(b, "</span>  <span id=\"traffic_mult\">");
30813         if (multiplier) buffer_append_string_len(b, &multiplier, 1);
30814 -       BUFFER_APPEND_STRING_CONST(b, "byte</td></tr>\n");
30815 +       BUFFER_APPEND_STRING_CONST(b, "</span>byte</td></tr>\n");
30816  
30817  
30818  
30819         BUFFER_APPEND_STRING_CONST(b, "<tr><th colspan=\"2\">average (since start)</th></tr>\n");
30820 -       
30821 -       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\">");
30822 +
30823 +       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\"><span id=\"requests_avg\">");
30824         avg = p->abs_requests / (srv->cur_ts - srv->startup_ts);
30825  
30826         mod_status_get_multiplier(&avg, &multiplier, 1000);
30827  
30828         buffer_append_long(b, avg);
30829 -       BUFFER_APPEND_STRING_CONST(b, " ");
30830 +       BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"requests_avg_mult\">");
30831         if (multiplier) buffer_append_string_len(b, &multiplier, 1);
30832 -       BUFFER_APPEND_STRING_CONST(b, "req/s</td></tr>\n");
30833 -       
30834 -       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\">");
30835 +       BUFFER_APPEND_STRING_CONST(b, "</span>req/s</td></tr>\n");
30836 +
30837 +       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\"><span id=\"traffic_avg\">");
30838         avg = p->abs_traffic_out / (srv->cur_ts - srv->startup_ts);
30839  
30840         mod_status_get_multiplier(&avg, &multiplier, 1024);
30841  
30842         sprintf(buf, "%.2f", avg);
30843         buffer_append_string(b, buf);
30844 -       BUFFER_APPEND_STRING_CONST(b, " ");
30845 +       BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"traffic_avg_mult\">");
30846         if (multiplier) buffer_append_string_len(b, &multiplier, 1);
30847 -       BUFFER_APPEND_STRING_CONST(b, "byte/s</td></tr>\n");
30848 +       BUFFER_APPEND_STRING_CONST(b, "</span>byte/s</td></tr>\n");
30849  
30850 -       
30851 -       
30852 +
30853 +
30854         BUFFER_APPEND_STRING_CONST(b, "<tr><th colspan=\"2\">average (5s sliding average)</th></tr>\n");
30855         for (j = 0, avg = 0; j < 5; j++) {
30856                 avg += p->mod_5s_requests[j];
30857         }
30858 -       
30859 +
30860         avg /= 5;
30861 -       
30862 -       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\">");
30863  
30864 +       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Requests</td><td class=\"string\"><span id=\"requests_sliding_avg\">");
30865 +
30866         mod_status_get_multiplier(&avg, &multiplier, 1000);
30867  
30868         buffer_append_long(b, avg);
30869 -       BUFFER_APPEND_STRING_CONST(b, " ");
30870 +       BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"requests_sliding_avg_mult\">");
30871         if (multiplier) buffer_append_string_len(b, &multiplier, 1);
30872 -       
30873 -       BUFFER_APPEND_STRING_CONST(b, "req/s</td></tr>\n");
30874 -       
30875 +
30876 +       BUFFER_APPEND_STRING_CONST(b, "</span>req/s</td></tr>\n");
30877 +
30878         for (j = 0, avg = 0; j < 5; j++) {
30879                 avg += p->mod_5s_traffic_out[j];
30880         }
30881 -       
30882 +
30883         avg /= 5;
30884 -       
30885 -       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\">");
30886  
30887 +       BUFFER_APPEND_STRING_CONST(b, "<tr><td>Traffic</td><td class=\"string\"><span id=\"requests_sliding_traffic\">");
30888 +
30889         mod_status_get_multiplier(&avg, &multiplier, 1024);
30890  
30891         sprintf(buf, "%.2f", avg);
30892         buffer_append_string(b, buf);
30893 -       BUFFER_APPEND_STRING_CONST(b, " ");
30894 +       BUFFER_APPEND_STRING_CONST(b, "</span> <span id=\"requests_sliding_traffic_mult\">");
30895         if (multiplier) buffer_append_string_len(b, &multiplier, 1);
30896 -       BUFFER_APPEND_STRING_CONST(b, "byte/s</td></tr>\n");
30897 -       
30898 +       BUFFER_APPEND_STRING_CONST(b, "</span>byte/s</td></tr>\n");
30899 +
30900         BUFFER_APPEND_STRING_CONST(b, "</table>\n");
30901 -       
30902 -       
30903 +
30904 +
30905         BUFFER_APPEND_STRING_CONST(b, "<hr />\n<pre><b>legend</b>\n");
30906         BUFFER_APPEND_STRING_CONST(b, ". = connect, C = close, E = hard error\n");
30907         BUFFER_APPEND_STRING_CONST(b, "r = read, R = read-POST, W = write, h = handle-request\n");
30908         BUFFER_APPEND_STRING_CONST(b, "q = request-start,  Q = request-end\n");
30909         BUFFER_APPEND_STRING_CONST(b, "s = response-start, S = response-end\n");
30910 -       
30911 -       BUFFER_APPEND_STRING_CONST(b, "<b>");
30912 +
30913 +       BUFFER_APPEND_STRING_CONST(b, "<strong><span id=\"connections\">");
30914         buffer_append_long(b, srv->conns->used);
30915 -       BUFFER_APPEND_STRING_CONST(b, " connections</b>\n");
30916 -       
30917 +       BUFFER_APPEND_STRING_CONST(b, "</span> connections</strong>\n");
30918 +
30919         for (j = 0; j < srv->conns->used; j++) {
30920                 connection *c = srv->conns->ptr[j];
30921                 const char *state = connection_get_short_state(c->state);
30922 -               
30923 +
30924                 buffer_append_string_len(b, state, 1);
30925 -               
30926 +
30927                 if (((j + 1) % 50) == 0) {
30928                         BUFFER_APPEND_STRING_CONST(b, "\n");
30929                 }
30930         }
30931 -       
30932 +
30933         BUFFER_APPEND_STRING_CONST(b, "\n</pre><hr />\n<h2>Connections</h2>\n");
30934 -       
30935 -       BUFFER_APPEND_STRING_CONST(b, "<table class=\"status\">\n");
30936 +
30937 +       BUFFER_APPEND_STRING_CONST(b, "<table class=\"status\" summary=\"Current connections\" id=\"clients\">\n");
30938         BUFFER_APPEND_STRING_CONST(b, "<tr>");
30939         mod_status_header_append_sort(b, p_d, "Client IP");
30940         mod_status_header_append_sort(b, p_d, "Read");
30941 @@ -473,16 +472,16 @@
30942         mod_status_header_append_sort(b, p_d, "URI");
30943         mod_status_header_append_sort(b, p_d, "File");
30944         BUFFER_APPEND_STRING_CONST(b, "</tr>\n");
30945 -       
30946 +
30947         for (j = 0; j < srv->conns->used; j++) {
30948                 connection *c = srv->conns->ptr[j];
30949 -               
30950 -               BUFFER_APPEND_STRING_CONST(b, "<tr><td class=\"string\">");
30951 -               
30952 +
30953 +               BUFFER_APPEND_STRING_CONST(b, "<tr><td class=\"string ip\">");
30954 +
30955                 buffer_append_string(b, inet_ntop_cache_get_ip(srv, &(c->dst_addr)));
30956 -               
30957 -               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int\">");
30958 -               
30959 +
30960 +               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int bytes_read\">");
30961 +
30962                 if (con->request.content_length) {
30963                         buffer_append_long(b, c->request_content_queue->bytes_in);
30964                         BUFFER_APPEND_STRING_CONST(b, "/");
30965 @@ -490,55 +489,55 @@
30966                 } else {
30967                         BUFFER_APPEND_STRING_CONST(b, "0/0");
30968                 }
30969 -       
30970 -               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int\">");
30971 -               
30972 +
30973 +               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int bytes_written\">");
30974 +
30975                 buffer_append_off_t(b, chunkqueue_written(c->write_queue));
30976                 BUFFER_APPEND_STRING_CONST(b, "/");
30977                 buffer_append_off_t(b, chunkqueue_length(c->write_queue));
30978 -               
30979 -               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">");
30980 -               
30981 +
30982 +               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string state\">");
30983 +
30984                 buffer_append_string(b, connection_get_state(c->state));
30985 -               
30986 -               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int\">");
30987 -               
30988 +
30989 +               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"int time\">");
30990 +
30991                 buffer_append_long(b, srv->cur_ts - c->request_start);
30992 -               
30993 -               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">");
30994 -               
30995 +
30996 +               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string host\">");
30997 +
30998                 if (buffer_is_empty(c->server_name)) {
30999                         buffer_append_string_buffer(b, c->uri.authority);
31000                 }
31001                 else {
31002                         buffer_append_string_buffer(b, c->server_name);
31003                 }
31004 -               
31005 -               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">");
31006 -               
31007 +
31008 +               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string uri\">");
31009 +
31010                 if (!buffer_is_empty(c->uri.path)) {
31011                         buffer_append_string_encoded(b, CONST_BUF_LEN(c->uri.path), ENCODING_HTML);
31012                 }
31013 -               
31014 -               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string\">");
31015 -               
31016 +
31017 +               BUFFER_APPEND_STRING_CONST(b, "</td><td class=\"string file\">");
31018 +
31019                 buffer_append_string_buffer(b, c->physical.path);
31020 -               
31021 +
31022                 BUFFER_APPEND_STRING_CONST(b, "</td></tr>\n");
31023         }
31024 -       
31025 -       
31026 -       BUFFER_APPEND_STRING_CONST(b, 
31027 +
31028 +
31029 +       BUFFER_APPEND_STRING_CONST(b,
31030                       "</table>\n");
31031 -       
31032 -       
31033 -       BUFFER_APPEND_STRING_CONST(b, 
31034 +
31035 +
31036 +       BUFFER_APPEND_STRING_CONST(b,
31037                       " </body>\n"
31038                       "</html>\n"
31039                       );
31040 -       
31041 +
31042         response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
31043 -       
31044 +
31045         return 0;
31046  }
31047  
31048 @@ -548,7 +547,7 @@
31049         buffer *b;
31050         double avg;
31051         time_t ts;
31052 -       
31053 +
31054         b = chunkqueue_get_append_buffer(con->write_queue);
31055  
31056         /* output total number of requests */
31057 @@ -556,19 +555,19 @@
31058         avg = p->abs_requests;
31059         buffer_append_long(b, avg);
31060         BUFFER_APPEND_STRING_CONST(b, "\n");
31061 -       
31062 +
31063         /* output total traffic out in kbytes */
31064         BUFFER_APPEND_STRING_CONST(b, "Total kBytes: ");
31065         avg = p->abs_traffic_out / 1024;
31066         buffer_append_long(b, avg);
31067         BUFFER_APPEND_STRING_CONST(b, "\n");
31068 -       
31069 +
31070         /* output uptime */
31071         BUFFER_APPEND_STRING_CONST(b, "Uptime: ");
31072         ts = srv->cur_ts - srv->startup_ts;
31073         buffer_append_long(b, ts);
31074         BUFFER_APPEND_STRING_CONST(b, "\n");
31075 -       
31076 +
31077         /* output busy servers */
31078         BUFFER_APPEND_STRING_CONST(b, "BusyServers: ");
31079         buffer_append_long(b, srv->conns->used);
31080 @@ -577,7 +576,7 @@
31081         /* set text/plain output */
31082  
31083         response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/plain"));
31084 -       
31085 +
31086         return 0;
31087  }
31088  
31089 @@ -591,10 +590,10 @@
31090                 /* we have nothing to send */
31091                 con->http_status = 204;
31092                 con->file_finished = 1;
31093 -       
31094 +
31095                 return HANDLER_FINISHED;
31096         }
31097 -       
31098 +
31099         b = chunkqueue_get_append_buffer(con->write_queue);
31100  
31101         for (i = 0; i < st->used; i++) {
31102 @@ -605,27 +604,27 @@
31103                 buffer_append_long(b, ((data_integer *)(st->data[ndx]))->value);
31104                 buffer_append_string(b, "\n");
31105         }
31106 -       
31107 +
31108         response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/plain"));
31109 -       
31110 +
31111         con->http_status = 200;
31112         con->file_finished = 1;
31113 -       
31114 +
31115         return HANDLER_FINISHED;
31116  }
31117  
31118  
31119  static handler_t mod_status_handle_server_status(server *srv, connection *con, void *p_d) {
31120 -       
31121 +
31122         if (buffer_is_equal_string(con->uri.query, CONST_STR_LEN("auto"))) {
31123                 mod_status_handle_server_status_text(srv, con, p_d);
31124         } else {
31125                 mod_status_handle_server_status_html(srv, con, p_d);
31126         }
31127 -       
31128 +
31129         con->http_status = 200;
31130         con->file_finished = 1;
31131 -       
31132 +
31133         return HANDLER_FINISHED;
31134  }
31135  
31136 @@ -634,9 +633,9 @@
31137         plugin_data *p = p_d;
31138         buffer *b, *m = p->module_list;
31139         size_t i;
31140 -       
31141 -       struct ev_map { fdevent_handler_t et; const char *name; } event_handlers[] = 
31142 -       { 
31143 +
31144 +       struct ev_map { fdevent_handler_t et; const char *name; } event_handlers[] =
31145 +       {
31146                 /* - poll is most reliable
31147                  * - select works everywhere
31148                  * - linux-* are experimental
31149 @@ -661,10 +660,10 @@
31150  #endif
31151                 { FDEVENT_HANDLER_UNSET,          NULL }
31152         };
31153 -       
31154 +
31155         b = chunkqueue_get_append_buffer(con->write_queue);
31156 -       
31157 -       BUFFER_COPY_STRING_CONST(b, 
31158 +
31159 +       BUFFER_COPY_STRING_CONST(b,
31160                            "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
31161                            "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
31162                            "         \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"
31163 @@ -675,7 +674,7 @@
31164                            " <body>\n"
31165                            "  <h1>" PACKAGE_NAME " " PACKAGE_VERSION "</h1>\n"
31166                            "  <table border=\"1\">\n");
31167 -       
31168 +
31169         mod_status_header_append(b, "Server-Features");
31170  #ifdef HAVE_PCRE_H
31171         mod_status_row_append(b, "RegEx Conditionals", "enabled");
31172 @@ -683,21 +682,21 @@
31173         mod_status_row_append(b, "RegEx Conditionals", "disabled - pcre missing");
31174  #endif
31175         mod_status_header_append(b, "Network Engine");
31176 -       
31177 +
31178         for (i = 0; event_handlers[i].name; i++) {
31179                 if (event_handlers[i].et == srv->event_handler) {
31180                         mod_status_row_append(b, "fd-Event-Handler", event_handlers[i].name);
31181                         break;
31182                 }
31183         }
31184 -       
31185 +
31186         mod_status_header_append(b, "Config-File-Settings");
31187 -       
31188 +
31189         for (i = 0; i < srv->plugins.used; i++) {
31190                 plugin **ps = srv->plugins.ptr;
31191 -               
31192 +
31193                 plugin *pl = ps[i];
31194 -       
31195 +
31196                 if (i == 0) {
31197                         buffer_copy_string_buffer(m, pl->name);
31198                 } else {
31199 @@ -705,137 +704,135 @@
31200                         buffer_append_string_buffer(m, pl->name);
31201                 }
31202         }
31203 -       
31204 +
31205         mod_status_row_append(b, "Loaded Modules", m->ptr);
31206 -       
31207 +
31208         BUFFER_APPEND_STRING_CONST(b, "  </table>\n");
31209 -       
31210 -       BUFFER_APPEND_STRING_CONST(b, 
31211 +
31212 +       BUFFER_APPEND_STRING_CONST(b,
31213                       " </body>\n"
31214                       "</html>\n"
31215                       );
31216 -       
31217 +
31218         response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
31219 -       
31220 +
31221         con->http_status = 200;
31222         con->file_finished = 1;
31223 -       
31224 +
31225         return HANDLER_FINISHED;
31226  }
31227  
31228 -#define PATCH(x) \
31229 -       p->conf.x = s->x;
31230  static int mod_status_patch_connection(server *srv, connection *con, plugin_data *p) {
31231         size_t i, j;
31232         plugin_config *s = p->config_storage[0];
31233 -       
31234 -       PATCH(status_url);
31235 -       PATCH(config_url);
31236 -       PATCH(sort);
31237 -       PATCH(statistics_url);
31238 -       
31239 +
31240 +       PATCH_OPTION(status_url);
31241 +       PATCH_OPTION(config_url);
31242 +       PATCH_OPTION(sort);
31243 +       PATCH_OPTION(statistics_url);
31244 +
31245         /* skip the first, the global context */
31246         for (i = 1; i < srv->config_context->used; i++) {
31247                 data_config *dc = (data_config *)srv->config_context->data[i];
31248                 s = p->config_storage[i];
31249 -               
31250 +
31251                 /* condition didn't match */
31252                 if (!config_check_cond(srv, con, dc)) continue;
31253 -               
31254 +
31255                 /* merge config */
31256                 for (j = 0; j < dc->value->used; j++) {
31257                         data_unset *du = dc->value->data[j];
31258 -                       
31259 +
31260                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("status.status-url"))) {
31261 -                               PATCH(status_url);
31262 +                               PATCH_OPTION(status_url);
31263                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("status.config-url"))) {
31264 -                               PATCH(config_url);
31265 +                               PATCH_OPTION(config_url);
31266                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("status.enable-sort"))) {
31267 -                               PATCH(sort);
31268 +                               PATCH_OPTION(sort);
31269                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("status.statistics-url"))) {
31270 -                               PATCH(statistics_url);
31271 -                       } 
31272 +                               PATCH_OPTION(statistics_url);
31273 +                       }
31274                 }
31275         }
31276 -       
31277 +
31278         return 0;
31279  }
31280  
31281  static handler_t mod_status_handler(server *srv, connection *con, void *p_d) {
31282         plugin_data *p = p_d;
31283 -       
31284 +
31285         mod_status_patch_connection(srv, con, p);
31286 -       
31287 -       if (!buffer_is_empty(p->conf.status_url) && 
31288 +
31289 +       if (!buffer_is_empty(p->conf.status_url) &&
31290             buffer_is_equal(p->conf.status_url, con->uri.path)) {
31291                 return mod_status_handle_server_status(srv, con, p_d);
31292 -       } else if (!buffer_is_empty(p->conf.config_url) && 
31293 +       } else if (!buffer_is_empty(p->conf.config_url) &&
31294             buffer_is_equal(p->conf.config_url, con->uri.path)) {
31295                 return mod_status_handle_server_config(srv, con, p_d);
31296 -       } else if (!buffer_is_empty(p->conf.statistics_url) && 
31297 +       } else if (!buffer_is_empty(p->conf.statistics_url) &&
31298             buffer_is_equal(p->conf.statistics_url, con->uri.path)) {
31299                 return mod_status_handle_server_statistics(srv, con, p_d);
31300         }
31301 -       
31302 +
31303         return HANDLER_GO_ON;
31304  }
31305  
31306  TRIGGER_FUNC(mod_status_trigger) {
31307         plugin_data *p = p_d;
31308         size_t i;
31309 -       
31310 +
31311         /* check all connections */
31312         for (i = 0; i < srv->conns->used; i++) {
31313                 connection *c = srv->conns->ptr[i];
31314 -               
31315 +
31316                 p->bytes_written += c->bytes_written_cur_second;
31317         }
31318 -       
31319 +
31320         /* a sliding average */
31321         p->mod_5s_traffic_out[p->mod_5s_ndx] = p->bytes_written;
31322         p->mod_5s_requests   [p->mod_5s_ndx] = p->requests;
31323 -       
31324 +
31325         p->mod_5s_ndx = (p->mod_5s_ndx+1) % 5;
31326 -       
31327 +
31328         p->abs_traffic_out += p->bytes_written;
31329         p->rel_traffic_out += p->bytes_written;
31330 -       
31331 +
31332         p->bytes_written = 0;
31333 -       
31334 +
31335         /* reset storage - second */
31336         p->traffic_out = 0;
31337         p->requests    = 0;
31338 -       
31339 +
31340         return HANDLER_GO_ON;
31341  }
31342  
31343  REQUESTDONE_FUNC(mod_status_account) {
31344         plugin_data *p = p_d;
31345 -       
31346 +
31347         UNUSED(srv);
31348  
31349         p->requests++;
31350         p->rel_requests++;
31351         p->abs_requests++;
31352 -       
31353 +
31354         p->bytes_written += con->bytes_written_cur_second;
31355 -       
31356 +
31357         return HANDLER_GO_ON;
31358  }
31359  
31360  int mod_status_plugin_init(plugin *p) {
31361         p->version     = LIGHTTPD_VERSION_ID;
31362         p->name        = buffer_init_string("status");
31363 -       
31364 +
31365         p->init        = mod_status_init;
31366         p->cleanup     = mod_status_free;
31367         p->set_defaults= mod_status_set_defaults;
31368 -       
31369 +
31370         p->handle_uri_clean    = mod_status_handler;
31371         p->handle_trigger      = mod_status_trigger;
31372         p->handle_request_done = mod_status_account;
31373 -       
31374 +
31375         p->data        = NULL;
31376 -       
31377 +
31378         return 0;
31379  }
31380
31381 Property changes on: src/mod_status.c
31382 ___________________________________________________________________
31383 Name: svn:eol-style
31384    + native
31385
31386
31387 Property changes on: src/md5.c
31388 ___________________________________________________________________
31389 Name: svn:eol-style
31390    + native
31391
31392 Index: src/mod_sql_vhost_core.c
31393 ===================================================================
31394 --- src/mod_sql_vhost_core.c    (.../tags/lighttpd-1.4.11)      (revision 0)
31395 +++ src/mod_sql_vhost_core.c    (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
31396 @@ -0,0 +1,209 @@
31397 +#include <stdio.h>
31398 +#include <errno.h>
31399 +#include <fcntl.h>
31400 +#include <string.h>
31401 +
31402 +#ifdef HAVE_CONFIG_H
31403 +#include "config.h"
31404 +#endif
31405 +
31406 +#include "plugin.h"
31407 +#include "log.h"
31408 +
31409 +#include "stat_cache.h"
31410 +
31411 +#include "mod_sql_vhost_core.h"
31412 +
31413 +#define plugin_data mod_sql_vhost_core_plugin_data
31414 +#define plugin_config mod_sql_vhost_core_plugin_config
31415 +
31416 +/* init the plugin data */
31417 +INIT_FUNC(mod_sql_vhost_core_init) {
31418 +       plugin_data *p;
31419 +
31420 +       p = calloc(1, sizeof(*p));
31421 +
31422 +       p->docroot = buffer_init();
31423 +       p->host = buffer_init();
31424 +
31425 +       return p;
31426 +}
31427 +
31428 +/* cleanup the plugin data */
31429 +SERVER_FUNC(mod_sql_vhost_core_cleanup) {
31430 +       plugin_data *p = p_d;
31431 +
31432 +       UNUSED(srv);
31433 +
31434 +       if (!p) return HANDLER_GO_ON;
31435 +
31436 +       if (p->config_storage) {
31437 +               size_t i;
31438 +               for (i = 0; i < srv->config_context->used; i++) {
31439 +                       plugin_config *s = p->config_storage[i];
31440 +
31441 +                       if (!s) continue;
31442 +
31443 +                       buffer_free(s->db);
31444 +                       buffer_free(s->user);
31445 +                       buffer_free(s->pass);
31446 +                       buffer_free(s->sock);
31447 +                       buffer_free(s->backend);
31448 +
31449 +                       free(s);
31450 +               }
31451 +               free(p->config_storage);
31452 +       }
31453 +       buffer_free(p->docroot);
31454 +       buffer_free(p->host);
31455 +
31456 +       free(p);
31457 +
31458 +       return HANDLER_GO_ON;
31459 +}
31460 +
31461 +/* set configuration values */
31462 +SERVER_FUNC(mod_sql_vhost_core_set_defaults) {
31463 +       plugin_data *p = p_d;
31464 +
31465 +       size_t i = 0;
31466 +
31467 +       config_values_t cv[] = {
31468 +               { "sql-vhost.db",       NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER }, /* 0 * e.g. vhost */
31469 +               { "sql-vhost.user",     NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER }, /* 1 * lighty */
31470 +               { "sql-vhost.pass",     NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER }, /* 2 * secrect */
31471 +               { "sql-vhost.sock",     NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER }, /* 3 * /tmp/mysql.sock */
31472 +               { "sql-vhost.select-vhost", NULL, T_CONFIG_STRING,      T_CONFIG_SCOPE_SERVER }, /* 4 * SELECT ... FROM hosts WHERE hostname = ? */
31473 +               { "sql-vhost.hostname", NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER }, /* 5 * 127.0.0.1 */
31474 +               { "sql-vhost.port",     NULL, T_CONFIG_SHORT,   T_CONFIG_SCOPE_SERVER }, /* 6 * 3306 */
31475 +               { "sql-vhost.backend",  NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER }, /* 7 * mysql */
31476 +
31477 +               /* backward compat */
31478 +               { "mysql-vhost.db",     NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER }, /* 8 == 0 */
31479 +               { "mysql-vhost.user",   NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER }, /* 9 == 1 */
31480 +               { "mysql-vhost.pass",   NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER }, /* 10 == 2 */
31481 +               { "mysql-vhost.sock",   NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER }, /* 11 == 3 */
31482 +               { "mysql-vhost.sql",    NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER }, /* 12 == 4 */
31483 +               { "mysql-vhost.hostname", NULL, T_CONFIG_STRING,T_CONFIG_SCOPE_SERVER }, /* 13 == 5 */
31484 +               { "mysql-vhost.port",   NULL, T_CONFIG_SHORT,   T_CONFIG_SCOPE_SERVER }, /* 14 == 6 */
31485 +
31486 +                { NULL,                        NULL, T_CONFIG_UNSET,   T_CONFIG_SCOPE_UNSET }
31487 +        };
31488 +
31489 +       p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
31490 +
31491 +       for (i = 0; i < srv->config_context->used; i++) {
31492 +               plugin_config *s;
31493 +
31494 +               s = calloc(1, sizeof(plugin_config));
31495 +               s->db = buffer_init();
31496 +               s->user = buffer_init();
31497 +               s->pass = buffer_init();
31498 +               s->sock = buffer_init();
31499 +               s->hostname = buffer_init();
31500 +               s->backend = buffer_init();
31501 +               s->port   = 0;               /* default port for mysql */
31502 +               s->select_vhost = buffer_init();
31503 +               s->backend_data = NULL;
31504 +
31505 +               cv[0].destination = s->db;
31506 +               cv[1].destination = s->user;
31507 +               cv[2].destination = s->pass;
31508 +               cv[3].destination = s->sock;
31509 +               cv[4].destination = s->select_vhost;
31510 +               cv[5].destination = s->hostname;
31511 +               cv[6].destination = &(s->port);
31512 +               cv[7].destination = s->backend;
31513 +
31514 +               /* backend compat */
31515 +               cv[8].destination = cv[0].destination;
31516 +               cv[9].destination = cv[1].destination;
31517 +               cv[10].destination = cv[2].destination;
31518 +               cv[11].destination = cv[3].destination;
31519 +               cv[12].destination = cv[4].destination;
31520 +               cv[13].destination = cv[5].destination;
31521 +               cv[14].destination = cv[6].destination;
31522 +
31523 +               p->config_storage[i] = s;
31524 +
31525 +               if (config_insert_values_global(srv,
31526 +                       ((data_config *)srv->config_context->data[i])->value,
31527 +                       cv)) return HANDLER_ERROR;
31528 +
31529 +               /* we only parse the config, the backend plugin will patch itself into the plugin-struct */
31530 +       }
31531 +
31532 +        return HANDLER_GO_ON;
31533 +}
31534 +
31535 +static int mod_sql_vhost_core_patch_connection(server *srv, connection *con, plugin_data *p) {
31536 +       size_t i;
31537 +       plugin_config *s = p->config_storage[0];
31538 +
31539 +       PATCH_OPTION(backend_data);
31540 +       PATCH_OPTION(get_vhost);
31541 +
31542 +       /* skip the first, the global context */
31543 +       for (i = 1; i < srv->config_context->used; i++) {
31544 +               data_config *dc = (data_config *)srv->config_context->data[i];
31545 +               s = p->config_storage[i];
31546 +
31547 +               /* condition didn't match */
31548 +               if (!config_check_cond(srv, con, dc)) continue;
31549 +
31550 +               if (s->backend_data) {
31551 +                       PATCH_OPTION(backend_data);
31552 +                       PATCH_OPTION(get_vhost);
31553 +               }
31554 +       }
31555 +
31556 +       return 0;
31557 +}
31558 +
31559 +/* handle document root request */
31560 +CONNECTION_FUNC(mod_sql_vhost_core_handle_docroot) {
31561 +       plugin_data *p = p_d;
31562 +       stat_cache_entry *sce;
31563 +
31564 +       /* no host specified? */
31565 +       if (!con->uri.authority->used) return HANDLER_GO_ON;
31566 +
31567 +       mod_sql_vhost_core_patch_connection(srv, con, p);
31568 +
31569 +       /* do we have backend ? */
31570 +       if (!p->conf.get_vhost) return HANDLER_GO_ON;
31571 +
31572 +       /* ask the backend for the data */
31573 +       if (0 != p->conf.get_vhost(srv, con, p->conf.backend_data, p->docroot, p->host)) {
31574 +               return HANDLER_GO_ON;
31575 +       }
31576 +
31577 +       if (HANDLER_ERROR == stat_cache_get_entry(srv, con, p->docroot, &sce)) {
31578 +               log_error_write(srv, __FILE__, __LINE__, "sb", strerror(errno), p->docroot);
31579 +               return HANDLER_GO_ON;
31580 +       }
31581 +        if (!S_ISDIR(sce->st.st_mode)) {
31582 +               log_error_write(srv, __FILE__, __LINE__, "sb", "Not a directory", p->docroot);
31583 +               return HANDLER_GO_ON;
31584 +       }
31585 +
31586 +       buffer_copy_string_buffer(con->server_name, p->host);
31587 +       buffer_copy_string_buffer(con->physical.doc_root, p->docroot);
31588 +
31589 +       return HANDLER_GO_ON;
31590 +}
31591 +
31592 +/* this function is called at dlopen() time and inits the callbacks */
31593 +int mod_sql_vhost_core_plugin_init(plugin *p) {
31594 +       p->version     = LIGHTTPD_VERSION_ID;
31595 +       p->name                         = buffer_init_string("mod_sql_vhost_core");
31596 +
31597 +       p->init                         = mod_sql_vhost_core_init;
31598 +       p->cleanup                      = mod_sql_vhost_core_cleanup;
31599 +
31600 +       p->set_defaults                 = mod_sql_vhost_core_set_defaults;
31601 +       p->handle_docroot               = mod_sql_vhost_core_handle_docroot;
31602 +
31603 +       return 0;
31604 +}
31605 +
31606 Index: src/mod_compress.c
31607 ===================================================================
31608 --- src/mod_compress.c  (.../tags/lighttpd-1.4.11)      (revision 1159)
31609 +++ src/mod_compress.c  (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
31610 @@ -2,7 +2,6 @@
31611  #include <sys/stat.h>
31612  
31613  #include <fcntl.h>
31614 -#include <unistd.h>
31615  #include <ctype.h>
31616  #include <stdlib.h>
31617  #include <string.h>
31618 @@ -14,6 +13,7 @@
31619  #include "buffer.h"
31620  #include "response.h"
31621  #include "stat_cache.h"
31622 +#include "http_chunk.h"
31623  
31624  #include "plugin.h"
31625  
31626 @@ -33,6 +33,7 @@
31627  #endif
31628  
31629  #include "sys-mmap.h"
31630 +#include "sys-files.h"
31631  
31632  /* request: accept-encoding */
31633  #define HTTP_ACCEPT_ENCODING_IDENTITY BV(0)
31634 @@ -55,97 +56,127 @@
31635         PLUGIN_DATA;
31636         buffer *ofn;
31637         buffer *b;
31638 -       
31639 +
31640         plugin_config **config_storage;
31641 -       plugin_config conf; 
31642 +       plugin_config conf;
31643  } plugin_data;
31644  
31645  INIT_FUNC(mod_compress_init) {
31646         plugin_data *p;
31647 -       
31648 +
31649         p = calloc(1, sizeof(*p));
31650 -       
31651 +
31652         p->ofn = buffer_init();
31653         p->b = buffer_init();
31654 -       
31655 +
31656         return p;
31657  }
31658  
31659  FREE_FUNC(mod_compress_free) {
31660         plugin_data *p = p_d;
31661 -       
31662 +
31663         UNUSED(srv);
31664  
31665         if (!p) return HANDLER_GO_ON;
31666 -       
31667 +
31668         buffer_free(p->ofn);
31669         buffer_free(p->b);
31670 -       
31671 +
31672         if (p->config_storage) {
31673                 size_t i;
31674                 for (i = 0; i < srv->config_context->used; i++) {
31675                         plugin_config *s = p->config_storage[i];
31676  
31677                         if (!s) continue;
31678 -                       
31679 +
31680                         array_free(s->compress);
31681                         buffer_free(s->compress_cache_dir);
31682 -                       
31683 +
31684                         free(s);
31685                 }
31686                 free(p->config_storage);
31687         }
31688 -       
31689 -       
31690 +
31691 +
31692         free(p);
31693 -       
31694 +
31695         return HANDLER_GO_ON;
31696  }
31697  
31698 +void mkdir_recursive(const char *dir) {
31699 +
31700 +       char dir_copy[256];
31701 +       char *p = dir_copy;
31702 +
31703 +       if (!dir || !dir[0])
31704 +               return;
31705 +
31706 +       strncpy(dir_copy, dir, sizeof(dir_copy) / sizeof(dir_copy[0]));
31707 +
31708 +       while ((p = strchr(p + 1, '/')) != NULL) {
31709 +
31710 +               *p = '\0';
31711 +               if ((mkdir(dir_copy, 0700) != 0) && (errno != EEXIST))
31712 +                       return;
31713 +
31714 +               *p++ = '/';
31715 +       }
31716 +
31717 +       mkdir(dir, 0700);
31718 +}
31719 +
31720  SETDEFAULTS_FUNC(mod_compress_setdefaults) {
31721         plugin_data *p = p_d;
31722         size_t i = 0;
31723 -       
31724 -       config_values_t cv[] = { 
31725 +
31726 +       config_values_t cv[] = {
31727                 { "compress.cache-dir",             NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
31728                 { "compress.filetype",              NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },
31729                 { "compress.max-filesize",          NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },
31730                 { NULL,                             NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
31731         };
31732 -       
31733 +
31734         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
31735 -       
31736 +
31737         for (i = 0; i < srv->config_context->used; i++) {
31738                 plugin_config *s;
31739 -               
31740 +
31741                 s = calloc(1, sizeof(plugin_config));
31742                 s->compress_cache_dir = buffer_init();
31743                 s->compress = array_init();
31744                 s->compress_max_filesize = 0;
31745 -               
31746 +
31747                 cv[0].destination = s->compress_cache_dir;
31748                 cv[1].destination = s->compress;
31749                 cv[2].destination = &(s->compress_max_filesize);
31750 -               
31751 +
31752                 p->config_storage[i] = s;
31753 -       
31754 +
31755                 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
31756                         return HANDLER_ERROR;
31757                 }
31758 -               
31759 +
31760                 if (!buffer_is_empty(s->compress_cache_dir)) {
31761                         struct stat st;
31762                         if (0 != stat(s->compress_cache_dir->ptr, &st)) {
31763 -                               log_error_write(srv, __FILE__, __LINE__, "sbs", "can't stat compress.cache-dir", 
31764 +
31765 +                               log_error_write(srv, __FILE__, __LINE__, "sbs", "can't stat compress.cache-dir, attempting to create",
31766                                                 s->compress_cache_dir, strerror(errno));
31767 -                               
31768 -                               return HANDLER_ERROR;
31769 +                               mkdir_recursive(s->compress_cache_dir->ptr);
31770 +
31771 +                               if (0 != stat(s->compress_cache_dir->ptr, &st)) {
31772 +
31773 +                                       log_error_write(srv, __FILE__, __LINE__, "sbs", "can't stat compress.cache-dir, create failed",
31774 +                                                                       s->compress_cache_dir, strerror(errno));
31775 +
31776 +                                       return HANDLER_ERROR;
31777 +                               }
31778                         }
31779                 }
31780         }
31781 -       
31782 +
31783         return HANDLER_GO_ON;
31784 -       
31785 +
31786  }
31787  
31788  #ifdef USE_ZLIB
31789 @@ -153,32 +184,32 @@
31790         unsigned char *c;
31791         unsigned long crc;
31792         z_stream z;
31793 -       
31794 +
31795         UNUSED(srv);
31796         UNUSED(con);
31797  
31798         z.zalloc = Z_NULL;
31799         z.zfree = Z_NULL;
31800         z.opaque = Z_NULL;
31801 -       
31802 -       if (Z_OK != deflateInit2(&z, 
31803 +
31804 +       if (Z_OK != deflateInit2(&z,
31805                                  Z_DEFAULT_COMPRESSION,
31806 -                                Z_DEFLATED, 
31807 +                                Z_DEFLATED,
31808                                  -MAX_WBITS,  /* supress zlib-header */
31809                                  8,
31810                                  Z_DEFAULT_STRATEGY)) {
31811                 return -1;
31812         }
31813 -               
31814 +
31815         z.next_in = (unsigned char *)start;
31816         z.avail_in = st_size;
31817         z.total_in = 0;
31818 -               
31819 -                       
31820 +
31821 +
31822         buffer_prepare_copy(p->b, (z.avail_in * 1.1) + 12 + 18);
31823 -               
31824 +
31825         /* write gzip header */
31826 -               
31827 +
31828         c = (unsigned char *)p->b->ptr;
31829         c[0] = 0x1f;
31830         c[1] = 0x8b;
31831 @@ -190,24 +221,24 @@
31832         c[7] = (mtime >> 24) & 0xff;
31833         c[8] = 0x00; /* extra flags */
31834         c[9] = 0x03; /* UNIX */
31835 -       
31836 +
31837         p->b->used = 10;
31838         z.next_out = (unsigned char *)p->b->ptr + p->b->used;
31839         z.avail_out = p->b->size - p->b->used - 8;
31840         z.total_out = 0;
31841 -       
31842 +
31843         if (Z_STREAM_END != deflate(&z, Z_FINISH)) {
31844                 deflateEnd(&z);
31845                 return -1;
31846         }
31847 -       
31848 +
31849         /* trailer */
31850         p->b->used += z.total_out;
31851 -       
31852 +
31853         crc = generate_crc32c(start, st_size);
31854 -               
31855 +
31856         c = (unsigned char *)p->b->ptr + p->b->used;
31857 -               
31858 +
31859         c[0] = (crc >>  0) & 0xff;
31860         c[1] = (crc >>  8) & 0xff;
31861         c[2] = (crc >> 16) & 0xff;
31862 @@ -221,51 +252,51 @@
31863         if (Z_OK != deflateEnd(&z)) {
31864                 return -1;
31865         }
31866 -       
31867 +
31868         return 0;
31869  }
31870  
31871  static int deflate_file_to_buffer_deflate(server *srv, connection *con, plugin_data *p, unsigned char *start, off_t st_size) {
31872         z_stream z;
31873 -       
31874 +
31875         UNUSED(srv);
31876         UNUSED(con);
31877  
31878         z.zalloc = Z_NULL;
31879         z.zfree = Z_NULL;
31880         z.opaque = Z_NULL;
31881 -       
31882 -       if (Z_OK != deflateInit2(&z, 
31883 +
31884 +       if (Z_OK != deflateInit2(&z,
31885                                  Z_DEFAULT_COMPRESSION,
31886 -                                Z_DEFLATED, 
31887 +                                Z_DEFLATED,
31888                                  -MAX_WBITS,  /* supress zlib-header */
31889                                  8,
31890                                  Z_DEFAULT_STRATEGY)) {
31891                 return -1;
31892         }
31893 -               
31894 +
31895         z.next_in = start;
31896         z.avail_in = st_size;
31897         z.total_in = 0;
31898 -               
31899 +
31900         buffer_prepare_copy(p->b, (z.avail_in * 1.1) + 12);
31901 -       
31902 +
31903         z.next_out = (unsigned char *)p->b->ptr;
31904         z.avail_out = p->b->size;
31905         z.total_out = 0;
31906 -       
31907 +
31908         if (Z_STREAM_END != deflate(&z, Z_FINISH)) {
31909                 deflateEnd(&z);
31910                 return -1;
31911         }
31912 -       
31913 +
31914         /* trailer */
31915         p->b->used += z.total_out;
31916 -       
31917 +
31918         if (Z_OK != deflateEnd(&z)) {
31919                 return -1;
31920         }
31921 -       
31922 +
31923         return 0;
31924  }
31925  
31926 @@ -274,48 +305,48 @@
31927  #ifdef USE_BZ2LIB
31928  static int deflate_file_to_buffer_bzip2(server *srv, connection *con, plugin_data *p, unsigned char *start, off_t st_size) {
31929         bz_stream bz;
31930 -       
31931 +
31932         UNUSED(srv);
31933         UNUSED(con);
31934  
31935         bz.bzalloc = NULL;
31936         bz.bzfree = NULL;
31937         bz.opaque = NULL;
31938 -       
31939 -       if (BZ_OK != BZ2_bzCompressInit(&bz, 
31940 +
31941 +       if (BZ_OK != BZ2_bzCompressInit(&bz,
31942                                         9, /* blocksize = 900k */
31943                                         0, /* no output */
31944                                         0)) { /* workFactor: default */
31945                 return -1;
31946         }
31947 -               
31948 +
31949         bz.next_in = (char *)start;
31950         bz.avail_in = st_size;
31951         bz.total_in_lo32 = 0;
31952         bz.total_in_hi32 = 0;
31953 -               
31954 +
31955         buffer_prepare_copy(p->b, (bz.avail_in * 1.1) + 12);
31956 -       
31957 +
31958         bz.next_out = p->b->ptr;
31959         bz.avail_out = p->b->size;
31960         bz.total_out_lo32 = 0;
31961         bz.total_out_hi32 = 0;
31962 -       
31963 +
31964         if (BZ_STREAM_END != BZ2_bzCompress(&bz, BZ_FINISH)) {
31965                 BZ2_bzCompressEnd(&bz);
31966                 return -1;
31967         }
31968 -       
31969 +
31970         /* file is too large for now */
31971         if (bz.total_out_hi32) return -1;
31972 -       
31973 +
31974         /* trailer */
31975         p->b->used = bz.total_out_lo32;
31976 -       
31977 +
31978         if (BZ_OK != BZ2_bzCompressEnd(&bz)) {
31979                 return -1;
31980         }
31981 -       
31982 +
31983         return 0;
31984  }
31985  #endif
31986 @@ -326,47 +357,50 @@
31987         void *start;
31988         const char *filename = fn->ptr;
31989         ssize_t r;
31990 -       
31991 +       stat_cache_entry *compressed_sce = NULL;
31992 +
31993 +       if (buffer_is_empty(p->conf.compress_cache_dir)) return -1;
31994 +
31995         /* overflow */
31996         if ((off_t)(sce->st.st_size * 1.1) < sce->st.st_size) return -1;
31997 -       
31998 -       /* don't mmap files > 128Mb 
31999 -        * 
32000 +
32001 +       /* don't mmap files > 128Mb
32002 +        *
32003          * we could use a sliding window, but currently there is no need for it
32004          */
32005 -       
32006 +
32007         if (sce->st.st_size > 128 * 1024 * 1024) return -1;
32008 -       
32009 +
32010         buffer_reset(p->ofn);
32011         buffer_copy_string_buffer(p->ofn, p->conf.compress_cache_dir);
32012 -       BUFFER_APPEND_SLASH(p->ofn);
32013 -       
32014 +       PATHNAME_APPEND_SLASH(p->ofn);
32015 +
32016         if (0 == strncmp(con->physical.path->ptr, con->physical.doc_root->ptr, con->physical.doc_root->used-1)) {
32017                 size_t offset = p->ofn->used - 1;
32018                 char *dir, *nextdir;
32019 -               
32020 +
32021                 buffer_append_string(p->ofn, con->physical.path->ptr + con->physical.doc_root->used - 1);
32022 -               
32023 +
32024                 buffer_copy_string_buffer(p->b, p->ofn);
32025 -               
32026 +
32027                 /* mkdir -p ... */
32028                 for (dir = p->b->ptr + offset; NULL != (nextdir = strchr(dir, '/')); dir = nextdir + 1) {
32029                         *nextdir = '\0';
32030 -                       
32031 +
32032                         if (-1 == mkdir(p->b->ptr, 0700)) {
32033                                 if (errno != EEXIST) {
32034                                         log_error_write(srv, __FILE__, __LINE__, "sbss", "creating cache-directory", p->b, "failed", strerror(errno));
32035 -                                       
32036 +
32037                                         return -1;
32038                                 }
32039                         }
32040 -                       
32041 +
32042                         *nextdir = '/';
32043                 }
32044         } else {
32045                 buffer_append_string_buffer(p->ofn, con->uri.path);
32046         }
32047 -       
32048 +
32049         switch(type) {
32050         case HTTP_ACCEPT_ENCODING_GZIP:
32051                 buffer_append_string(p->ofn, "-gzip-");
32052 @@ -381,55 +415,64 @@
32053                 log_error_write(srv, __FILE__, __LINE__, "sd", "unknown compression type", type);
32054                 return -1;
32055         }
32056 -       
32057 +
32058         buffer_append_string_buffer(p->ofn, sce->etag);
32059 -       
32060 +
32061 +
32062 +       if (HANDLER_ERROR != stat_cache_get_entry(srv, con, p->ofn, &compressed_sce)) {
32063 +               /* file exists */
32064 +
32065 +               http_chunk_append_file(srv, con, p->ofn, 0, compressed_sce->st.st_size);
32066 +               con->file_finished = 1;
32067 +
32068 +               return 0;
32069 +       }
32070 +
32071         if (-1 == (ofd = open(p->ofn->ptr, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0600))) {
32072                 if (errno == EEXIST) {
32073                         /* cache-entry exists */
32074 -#if 0
32075 -                       log_error_write(srv, __FILE__, __LINE__, "bs", p->ofn, "compress-cache hit");
32076 -#endif
32077 -                       buffer_copy_string_buffer(con->physical.path, p->ofn);
32078 -                       
32079 -                       return 0;
32080 +
32081                 }
32082 -               
32083 -               log_error_write(srv, __FILE__, __LINE__, "sbss", "creating cachefile", p->ofn, "failed", strerror(errno));
32084 -               
32085 +
32086 +               log_error_write(srv, __FILE__, __LINE__, "sbss",
32087 +                               "creating cachefile", p->ofn,
32088 +                               "failed", strerror(errno));
32089 +
32090                 return -1;
32091         }
32092 -#if 0
32093 -       log_error_write(srv, __FILE__, __LINE__, "bs", p->ofn, "compress-cache miss");
32094 -#endif 
32095 +
32096         if (-1 == (ifd = open(filename, O_RDONLY | O_BINARY))) {
32097 -               log_error_write(srv, __FILE__, __LINE__, "sbss", "opening plain-file", fn, "failed", strerror(errno));
32098 -               
32099 +               log_error_write(srv, __FILE__, __LINE__, "sbss",
32100 +                               "opening plain-file", fn,
32101 +                               "failed", strerror(errno));
32102 +
32103                 close(ofd);
32104 -               
32105 +
32106                 return -1;
32107         }
32108 -       
32109 -       
32110 +
32111 +
32112         if (MAP_FAILED == (start = mmap(NULL, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0))) {
32113 -               log_error_write(srv, __FILE__, __LINE__, "sbss", "mmaping", fn, "failed", strerror(errno));
32114 -               
32115 +               log_error_write(srv, __FILE__, __LINE__, "sbss",
32116 +                               "mmaping", fn,
32117 +                               "failed", strerror(errno));
32118 +
32119                 close(ofd);
32120                 close(ifd);
32121                 return -1;
32122         }
32123 -       
32124 +
32125         switch(type) {
32126  #ifdef USE_ZLIB
32127 -       case HTTP_ACCEPT_ENCODING_GZIP: 
32128 +       case HTTP_ACCEPT_ENCODING_GZIP:
32129                 ret = deflate_file_to_buffer_gzip(srv, con, p, start, sce->st.st_size, sce->st.st_mtime);
32130                 break;
32131 -       case HTTP_ACCEPT_ENCODING_DEFLATE: 
32132 +       case HTTP_ACCEPT_ENCODING_DEFLATE:
32133                 ret = deflate_file_to_buffer_deflate(srv, con, p, start, sce->st.st_size);
32134                 break;
32135  #endif
32136  #ifdef USE_BZ2LIB
32137 -       case HTTP_ACCEPT_ENCODING_BZIP2: 
32138 +       case HTTP_ACCEPT_ENCODING_BZIP2:
32139                 ret = deflate_file_to_buffer_bzip2(srv, con, p, start, sce->st.st_size);
32140                 break;
32141  #endif
32142 @@ -437,26 +480,27 @@
32143                 ret = -1;
32144                 break;
32145         }
32146 -       
32147 +
32148         if (-1 == (r = write(ofd, p->b->ptr, p->b->used))) {
32149 -               munmap(start, sce->st.st_size); 
32150 +               munmap(start, sce->st.st_size);
32151                 close(ofd);
32152                 close(ifd);
32153                 return -1;
32154         }
32155 -       
32156 +
32157         if ((size_t)r != p->b->used) {
32158 -               
32159 +
32160         }
32161 -               
32162 +
32163         munmap(start, sce->st.st_size);
32164         close(ofd);
32165         close(ifd);
32166 -       
32167 +
32168         if (ret != 0) return -1;
32169 -       
32170 -       buffer_copy_string_buffer(con->physical.path, p->ofn);
32171 -       
32172 +
32173 +       http_chunk_append_file(srv, con, p->ofn, 0, r);
32174 +       con->file_finished = 1;
32175 +
32176         return 0;
32177  }
32178  
32179 @@ -465,43 +509,44 @@
32180         int ret = -1;
32181         void *start;
32182         buffer *b;
32183 -       
32184 +
32185         /* overflow */
32186         if ((off_t)(sce->st.st_size * 1.1) < sce->st.st_size) return -1;
32187 -       
32188 +
32189         /* don't mmap files > 128M
32190 -        * 
32191 +        *
32192          * we could use a sliding window, but currently there is no need for it
32193          */
32194 -       
32195 +
32196         if (sce->st.st_size > 128 * 1024 * 1024) return -1;
32197 -       
32198 -       
32199 +
32200         if (-1 == (ifd = open(fn->ptr, O_RDONLY | O_BINARY))) {
32201                 log_error_write(srv, __FILE__, __LINE__, "sbss", "opening plain-file", fn, "failed", strerror(errno));
32202 -               
32203 +
32204                 return -1;
32205         }
32206 -       
32207 -       
32208 -       if (MAP_FAILED == (start = mmap(NULL, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0))) {
32209 +
32210 +       start = mmap(NULL, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0);
32211 +
32212 +       close(ifd);
32213 +
32214 +       if (MAP_FAILED == start) {
32215                 log_error_write(srv, __FILE__, __LINE__, "sbss", "mmaping", fn, "failed", strerror(errno));
32216 -               
32217 -               close(ifd);
32218 +
32219                 return -1;
32220         }
32221 -       
32222 +
32223         switch(type) {
32224  #ifdef USE_ZLIB
32225 -       case HTTP_ACCEPT_ENCODING_GZIP: 
32226 +       case HTTP_ACCEPT_ENCODING_GZIP:
32227                 ret = deflate_file_to_buffer_gzip(srv, con, p, start, sce->st.st_size, sce->st.st_mtime);
32228                 break;
32229 -       case HTTP_ACCEPT_ENCODING_DEFLATE: 
32230 +       case HTTP_ACCEPT_ENCODING_DEFLATE:
32231                 ret = deflate_file_to_buffer_deflate(srv, con, p, start, sce->st.st_size);
32232                 break;
32233  #endif
32234  #ifdef USE_BZ2LIB
32235 -       case HTTP_ACCEPT_ENCODING_BZIP2: 
32236 +       case HTTP_ACCEPT_ENCODING_BZIP2:
32237                 ret = deflate_file_to_buffer_bzip2(srv, con, p, start, sce->st.st_size);
32238                 break;
32239  #endif
32240 @@ -509,69 +554,64 @@
32241                 ret = -1;
32242                 break;
32243         }
32244 -               
32245 +
32246         munmap(start, sce->st.st_size);
32247 -       close(ifd);
32248 -       
32249 +
32250         if (ret != 0) return -1;
32251 -       
32252 +
32253         chunkqueue_reset(con->write_queue);
32254         b = chunkqueue_get_append_buffer(con->write_queue);
32255         buffer_copy_memory(b, p->b->ptr, p->b->used + 1);
32256 -       
32257 +
32258         buffer_reset(con->physical.path);
32259 -       
32260 +
32261         con->file_finished = 1;
32262         con->file_started  = 1;
32263 -       
32264 +
32265         return 0;
32266  }
32267  
32268 -
32269 -#define PATCH(x) \
32270 -       p->conf.x = s->x;
32271  static int mod_compress_patch_connection(server *srv, connection *con, plugin_data *p) {
32272         size_t i, j;
32273         plugin_config *s = p->config_storage[0];
32274  
32275 -       PATCH(compress_cache_dir);
32276 -       PATCH(compress);
32277 -       PATCH(compress_max_filesize);
32278 -       
32279 +       PATCH_OPTION(compress_cache_dir);
32280 +       PATCH_OPTION(compress);
32281 +       PATCH_OPTION(compress_max_filesize);
32282 +
32283         /* skip the first, the global context */
32284         for (i = 1; i < srv->config_context->used; i++) {
32285                 data_config *dc = (data_config *)srv->config_context->data[i];
32286                 s = p->config_storage[i];
32287 -               
32288 +
32289                 /* condition didn't match */
32290                 if (!config_check_cond(srv, con, dc)) continue;
32291 -               
32292 +
32293                 /* merge config */
32294                 for (j = 0; j < dc->value->used; j++) {
32295                         data_unset *du = dc->value->data[j];
32296 -                       
32297 +
32298                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("compress.cache-dir"))) {
32299 -                               PATCH(compress_cache_dir);
32300 +                               PATCH_OPTION(compress_cache_dir);
32301                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("compress.filetype"))) {
32302 -                               PATCH(compress);
32303 +                               PATCH_OPTION(compress);
32304                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("compress.max-filesize"))) {
32305 -                               PATCH(compress_max_filesize);
32306 +                               PATCH_OPTION(compress_max_filesize);
32307                         }
32308                 }
32309         }
32310 -       
32311 +
32312         return 0;
32313  }
32314 -#undef PATCH
32315  
32316  PHYSICALPATH_FUNC(mod_compress_physical) {
32317         plugin_data *p = p_d;
32318         size_t m;
32319         off_t max_fsize;
32320         stat_cache_entry *sce = NULL;
32321 -       
32322 +
32323         /* only GET and POST can get compressed */
32324 -       if (con->request.http_method != HTTP_METHOD_GET && 
32325 +       if (con->request.http_method != HTTP_METHOD_GET &&
32326             con->request.http_method != HTTP_METHOD_POST) {
32327                 return HANDLER_GO_ON;
32328         }
32329 @@ -579,46 +619,49 @@
32330         if (buffer_is_empty(con->physical.path)) {
32331                 return HANDLER_GO_ON;
32332         }
32333 -       
32334 +
32335         mod_compress_patch_connection(srv, con, p);
32336 -       
32337 +
32338         max_fsize = p->conf.compress_max_filesize;
32339  
32340         stat_cache_get_entry(srv, con, con->physical.path, &sce);
32341  
32342         /* don't compress files that are too large as we need to much time to handle them */
32343         if (max_fsize && (sce->st.st_size >> 10) > max_fsize) return HANDLER_GO_ON;
32344 -               
32345 +
32346 +       /* compressing the file might lead to larger files instead */
32347 +       if (sce->st.st_size < 128) return HANDLER_GO_ON;
32348 +
32349         /* check if mimetype is in compress-config */
32350         for (m = 0; m < p->conf.compress->used; m++) {
32351                 data_string *compress_ds = (data_string *)p->conf.compress->data[m];
32352 -                       
32353 +
32354                 if (!compress_ds) {
32355                         log_error_write(srv, __FILE__, __LINE__, "sbb", "evil", con->physical.path, con->uri.path);
32356 -                       
32357 +
32358                         return HANDLER_GO_ON;
32359                 }
32360 -               
32361 +
32362                 if (buffer_is_equal(compress_ds->value, sce->content_type)) {
32363                         /* mimetype found */
32364                         data_string *ds;
32365 -                               
32366 +
32367                         /* the response might change according to Accept-Encoding */
32368                         response_header_insert(srv, con, CONST_STR_LEN("Vary"), CONST_STR_LEN("Accept-Encoding"));
32369 -                               
32370 +
32371                         if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Accept-Encoding"))) {
32372                                 int accept_encoding = 0;
32373                                 char *value = ds->value->ptr;
32374                                 int srv_encodings = 0;
32375                                 int matched_encodings = 0;
32376 -                               
32377 +
32378                                 /* get client side support encodings */
32379                                 if (NULL != strstr(value, "gzip")) accept_encoding |= HTTP_ACCEPT_ENCODING_GZIP;
32380                                 if (NULL != strstr(value, "deflate")) accept_encoding |= HTTP_ACCEPT_ENCODING_DEFLATE;
32381                                 if (NULL != strstr(value, "compress")) accept_encoding |= HTTP_ACCEPT_ENCODING_COMPRESS;
32382                                 if (NULL != strstr(value, "bzip2")) accept_encoding |= HTTP_ACCEPT_ENCODING_BZIP2;
32383                                 if (NULL != strstr(value, "identity")) accept_encoding |= HTTP_ACCEPT_ENCODING_IDENTITY;
32384 -                               
32385 +
32386                                 /* get server side supported ones */
32387  #ifdef USE_BZ2LIB
32388                                 srv_encodings |= HTTP_ACCEPT_ENCODING_BZIP2;
32389 @@ -627,18 +670,31 @@
32390                                 srv_encodings |= HTTP_ACCEPT_ENCODING_GZIP;
32391                                 srv_encodings |= HTTP_ACCEPT_ENCODING_DEFLATE;
32392  #endif
32393 -                               
32394 +
32395                                 /* find matching entries */
32396                                 matched_encodings = accept_encoding & srv_encodings;
32397 -                               
32398 +
32399                                 if (matched_encodings) {
32400                                         const char *dflt_gzip = "gzip";
32401                                         const char *dflt_deflate = "deflate";
32402                                         const char *dflt_bzip2 = "bzip2";
32403 -                                       
32404 +
32405                                         const char *compression_name = NULL;
32406                                         int compression_type = 0;
32407 -                                       
32408 +                                       buffer *mtime;
32409 +
32410 +                                       mtime = strftime_cache_get(srv, sce->st.st_mtime);
32411 +                                       etag_mutate(con->physical.etag, sce->etag);
32412 +
32413 +                                       response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), CONST_BUF_LEN(mtime));
32414 +                                       response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag));
32415 +
32416 +                                       /* perhaps we don't even have to compress the file as the browser still has the
32417 +                                        * current version */
32418 +                                       if (HANDLER_FINISHED == http_response_handle_cachable(srv, con, mtime)) {
32419 +                                               return HANDLER_FINISHED;
32420 +                                       }
32421 +
32422                                         /* select best matching encoding */
32423                                         if (matched_encodings & HTTP_ACCEPT_ENCODING_BZIP2) {
32424                                                 compression_type = HTTP_ACCEPT_ENCODING_BZIP2;
32425 @@ -650,31 +706,21 @@
32426                                                 compression_type = HTTP_ACCEPT_ENCODING_DEFLATE;
32427                                                 compression_name = dflt_deflate;
32428                                         }
32429 -                                       
32430 -                                       /* deflate it */
32431 -                                       if (p->conf.compress_cache_dir->used) {
32432 -                                               if (0 == deflate_file_to_file(srv, con, p,
32433 -                                                                             con->physical.path, sce, compression_type)) {
32434 -                                                       buffer *mtime;
32435 -                                                       
32436 -                                                       response_header_overwrite(srv, con, CONST_STR_LEN("Content-Encoding"), compression_name, strlen(compression_name));
32437 -                                                       
32438 -                                                       mtime = strftime_cache_get(srv, sce->st.st_mtime);
32439 -                                                       response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), CONST_BUF_LEN(mtime));
32440  
32441 -                                                       etag_mutate(con->physical.etag, sce->etag);
32442 -                                                       response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag));
32443 +                                       /* deflate it to file (cached) or to memory */
32444 +                                       if (0 == deflate_file_to_file(srv, con, p,
32445 +                                                       con->physical.path, sce, compression_type) ||
32446 +                                           0 == deflate_file_to_buffer(srv, con, p,
32447 +                                                       con->physical.path, sce, compression_type)) {
32448  
32449 -                                                       response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type));
32450 +                                               response_header_overwrite(srv, con,
32451 +                                                               CONST_STR_LEN("Content-Encoding"),
32452 +                                                               compression_name, strlen(compression_name));
32453  
32454 -                                                       return HANDLER_GO_ON;
32455 -                                               }
32456 -                                       } else if (0 == deflate_file_to_buffer(srv, con, p,
32457 -                                                                              con->physical.path, sce, compression_type)) {
32458 -                                                       
32459 -                                               response_header_overwrite(srv, con, CONST_STR_LEN("Content-Encoding"), compression_name, strlen(compression_name));
32460 -                                               response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type));
32461 -                                               
32462 +                                               response_header_overwrite(srv, con,
32463 +                                                               CONST_STR_LEN("Content-Type"),
32464 +                                                               CONST_BUF_LEN(sce->content_type));
32465 +
32466                                                 return HANDLER_FINISHED;
32467                                         }
32468                                         break;
32469 @@ -682,20 +728,20 @@
32470                         }
32471                 }
32472         }
32473 -       
32474 +
32475         return HANDLER_GO_ON;
32476  }
32477  
32478  int mod_compress_plugin_init(plugin *p) {
32479         p->version     = LIGHTTPD_VERSION_ID;
32480         p->name        = buffer_init_string("compress");
32481 -       
32482 +
32483         p->init        = mod_compress_init;
32484         p->set_defaults = mod_compress_setdefaults;
32485         p->handle_subrequest_start  = mod_compress_physical;
32486         p->cleanup     = mod_compress_free;
32487 -       
32488 +
32489         p->data        = NULL;
32490 -       
32491 +
32492         return 0;
32493  }
32494
32495 Property changes on: src/mod_compress.c
32496 ___________________________________________________________________
32497 Name: svn:eol-style
32498    + native
32499
32500 Index: src/md5.h
32501 ===================================================================
32502 --- src/md5.h   (.../tags/lighttpd-1.4.11)      (revision 1159)
32503 +++ src/md5.h   (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
32504 @@ -30,9 +30,15 @@
32505  # include <inttypes.h>
32506  #endif
32507  
32508 +#ifdef _WIN32
32509 +#define UINT4 unsigned __int32
32510 +#define UINT2 unsigned __int16
32511 +#define POINTER unsigned char *
32512 +#else
32513  #define UINT4 uint32_t
32514  #define UINT2 uint16_t
32515  #define POINTER unsigned char *
32516 +#endif
32517  
32518  /* MD5 context. */
32519  typedef struct {
32520
32521 Property changes on: src/md5.h
32522 ___________________________________________________________________
32523 Name: svn:eol-style
32524    + native
32525
32526
32527 Property changes on: src/.cvsignore
32528 ___________________________________________________________________
32529 Name: svn:eol-style
32530    + native
32531
32532 Index: src/mod_ssi.c
32533 ===================================================================
32534 --- src/mod_ssi.c       (.../tags/lighttpd-1.4.11)      (revision 1159)
32535 +++ src/mod_ssi.c       (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
32536 @@ -6,7 +6,6 @@
32537  #include <string.h>
32538  #include <errno.h>
32539  #include <time.h>
32540 -#include <unistd.h>
32541  
32542  #include "base.h"
32543  #include "log.h"
32544 @@ -23,6 +22,8 @@
32545  #include "inet_ntop_cache.h"
32546  
32547  #include "sys-socket.h"
32548 +#include "sys-strings.h"
32549 +#include "sys-files.h"
32550  
32551  #ifdef HAVE_PWD_H
32552  #include <pwd.h>
32553 @@ -39,15 +40,15 @@
32554  /* init the plugin data */
32555  INIT_FUNC(mod_ssi_init) {
32556         plugin_data *p;
32557 -       
32558 +
32559         p = calloc(1, sizeof(*p));
32560 -       
32561 +
32562         p->timefmt = buffer_init();
32563         p->stat_fn = buffer_init();
32564 -       
32565 +
32566         p->ssi_vars = array_init();
32567         p->ssi_cgi_env = array_init();
32568 -       
32569 +
32570         return p;
32571  }
32572  
32573 @@ -55,21 +56,21 @@
32574  FREE_FUNC(mod_ssi_free) {
32575         plugin_data *p = p_d;
32576         UNUSED(srv);
32577 -       
32578 +
32579         if (!p) return HANDLER_GO_ON;
32580 -       
32581 +
32582         if (p->config_storage) {
32583                 size_t i;
32584                 for (i = 0; i < srv->config_context->used; i++) {
32585                         plugin_config *s = p->config_storage[i];
32586 -                       
32587 +
32588                         array_free(s->ssi_extension);
32589 -                       
32590 +
32591                         free(s);
32592                 }
32593                 free(p->config_storage);
32594         }
32595 -       
32596 +
32597         array_free(p->ssi_vars);
32598         array_free(p->ssi_cgi_env);
32599  #ifdef HAVE_PCRE_H
32600 @@ -77,9 +78,9 @@
32601  #endif
32602         buffer_free(p->timefmt);
32603         buffer_free(p->stat_fn);
32604 -       
32605 +
32606         free(p);
32607 -       
32608 +
32609         return HANDLER_GO_ON;
32610  }
32611  
32612 @@ -92,36 +93,36 @@
32613         const char *errptr;
32614         int erroff;
32615  #endif
32616 -       
32617 -       config_values_t cv[] = { 
32618 +
32619 +       config_values_t cv[] = {
32620                 { "ssi.extension",              NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
32621                 { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
32622         };
32623 -       
32624 +
32625         if (!p) return HANDLER_ERROR;
32626 -       
32627 +
32628         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
32629 -       
32630 +
32631         for (i = 0; i < srv->config_context->used; i++) {
32632                 plugin_config *s;
32633 -               
32634 +
32635                 s = calloc(1, sizeof(plugin_config));
32636                 s->ssi_extension  = array_init();
32637 -               
32638 +
32639                 cv[0].destination = s->ssi_extension;
32640 -               
32641 +
32642                 p->config_storage[i] = s;
32643 -       
32644 +
32645                 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
32646                         return HANDLER_ERROR;
32647                 }
32648         }
32649 -       
32650 +
32651  #ifdef HAVE_PCRE_H
32652         /* allow 2 params */
32653         if (NULL == (p->ssi_regex = pcre_compile("<!--#([a-z]+)\\s+(?:([a-z]+)=\"(.*?)(?<!\\\\)\"\\s*)?(?:([a-z]+)=\"(.*?)(?<!\\\\)\"\\s*)?-->", 0, &errptr, &erroff, NULL))) {
32654                 log_error_write(srv, __FILE__, __LINE__, "sds",
32655 -                               "ssi: pcre ", 
32656 +                               "ssi: pcre ",
32657                                 erroff, errptr);
32658                 return HANDLER_ERROR;
32659         }
32660 @@ -130,52 +131,52 @@
32661                         "mod_ssi: pcre support is missing, please recompile with pcre support or remove mod_ssi from the list of modules");
32662         return HANDLER_ERROR;
32663  #endif
32664 -       
32665 +
32666         return HANDLER_GO_ON;
32667  }
32668  
32669  int ssi_env_add(array *env, const char *key, const char *val) {
32670         data_string *ds;
32671 -                       
32672 +
32673         if (NULL == (ds = (data_string *)array_get_unused_element(env, TYPE_STRING))) {
32674                 ds = data_string_init();
32675         }
32676         buffer_copy_string(ds->key,   key);
32677         buffer_copy_string(ds->value, val);
32678 -       
32679 +
32680         array_insert_unique(env, (data_unset *)ds);
32681 -       
32682 +
32683         return 0;
32684  }
32685  
32686  /**
32687   *
32688   *  the next two functions are take from fcgi.c
32689 - * 
32690 + *
32691   */
32692  
32693  static int ssi_env_add_request_headers(server *srv, connection *con, plugin_data *p) {
32694         size_t i;
32695 -       
32696 +
32697         for (i = 0; i < con->request.headers->used; i++) {
32698                 data_string *ds;
32699 -               
32700 +
32701                 ds = (data_string *)con->request.headers->data[i];
32702 -               
32703 +
32704                 if (ds->value->used && ds->key->used) {
32705                         size_t j;
32706                         buffer_reset(srv->tmp_buf);
32707 -                       
32708 +
32709                         /* don't forward the Authorization: Header */
32710                         if (0 == strcasecmp(ds->key->ptr, "AUTHORIZATION")) {
32711                                 continue;
32712                         }
32713 -                       
32714 +
32715                         if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) {
32716                                 buffer_copy_string(srv->tmp_buf, "HTTP_");
32717                                 srv->tmp_buf->used--;
32718                         }
32719 -                       
32720 +
32721                         buffer_prepare_append(srv->tmp_buf, ds->key->used + 2);
32722                         for (j = 0; j < ds->key->used - 1; j++) {
32723                                 char c = '_';
32724 @@ -189,33 +190,33 @@
32725                                 srv->tmp_buf->ptr[srv->tmp_buf->used++] = c;
32726                         }
32727                         srv->tmp_buf->ptr[srv->tmp_buf->used] = '\0';
32728 -                       
32729 +
32730                         ssi_env_add(p->ssi_cgi_env, srv->tmp_buf->ptr, ds->value->ptr);
32731                 }
32732         }
32733 -       
32734 +
32735         return 0;
32736  }
32737  
32738  static int build_ssi_cgi_vars(server *srv, connection *con, plugin_data *p) {
32739         char buf[32];
32740 -       
32741 +
32742         server_socket *srv_sock = con->srv_socket;
32743 -       
32744 +
32745  #ifdef HAVE_IPV6
32746         char b2[INET6_ADDRSTRLEN + 1];
32747  #endif
32748  
32749  #define CONST_STRING(x) \
32750                 x
32751 -       
32752 +
32753         array_reset(p->ssi_cgi_env);
32754 -       
32755 +
32756         ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_SOFTWARE"), PACKAGE_NAME"/"PACKAGE_VERSION);
32757         ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_NAME"),
32758  #ifdef HAVE_IPV6
32759 -                    inet_ntop(srv_sock->addr.plain.sa_family, 
32760 -                              srv_sock->addr.plain.sa_family == AF_INET6 ? 
32761 +                    inet_ntop(srv_sock->addr.plain.sa_family,
32762 +                              srv_sock->addr.plain.sa_family == AF_INET6 ?
32763                                (const void *) &(srv_sock->addr.ipv6.sin6_addr) :
32764                                (const void *) &(srv_sock->addr.ipv4.sin_addr),
32765                                b2, sizeof(b2)-1)
32766 @@ -224,28 +225,28 @@
32767  #endif
32768                      );
32769         ssi_env_add(p->ssi_cgi_env, CONST_STRING("GATEWAY_INTERFACE"), "CGI/1.1");
32770 -               
32771 -       ltostr(buf, 
32772 +
32773 +       ltostr(buf,
32774  #ifdef HAVE_IPV6
32775                ntohs(srv_sock->addr.plain.sa_family ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port)
32776  #else
32777                ntohs(srv_sock->addr.ipv4.sin_port)
32778  #endif
32779                );
32780 -       
32781 +
32782         ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_PORT"), buf);
32783 -       
32784 +
32785         ssi_env_add(p->ssi_cgi_env, CONST_STRING("REMOTE_ADDR"),
32786                     inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
32787 -       
32788 +
32789         if (con->authed_user->used) {
32790                 ssi_env_add(p->ssi_cgi_env, CONST_STRING("REMOTE_USER"),
32791                              con->authed_user->ptr);
32792         }
32793 -       
32794 +
32795         if (con->request.content_length > 0) {
32796                 /* CGI-SPEC 6.1.2 and FastCGI spec 6.3 */
32797 -               
32798 +
32799                 /* request.content_length < SSIZE_MAX, see request.c */
32800                 ltostr(buf, con->request.content_length);
32801                 ssi_env_add(p->ssi_cgi_env, CONST_STRING("CONTENT_LENGTH"), buf);
32802 @@ -271,30 +272,30 @@
32803         if (con->request.pathinfo->used) {
32804                 ssi_env_add(p->ssi_cgi_env, CONST_STRING("PATH_INFO"), con->request.pathinfo->ptr);
32805         }
32806 -               
32807 +
32808         ssi_env_add(p->ssi_cgi_env, CONST_STRING("SCRIPT_FILENAME"), con->physical.path->ptr);
32809         ssi_env_add(p->ssi_cgi_env, CONST_STRING("DOCUMENT_ROOT"), con->physical.doc_root->ptr);
32810 -       
32811 +
32812         ssi_env_add(p->ssi_cgi_env, CONST_STRING("REQUEST_URI"), con->request.uri->ptr);
32813         ssi_env_add(p->ssi_cgi_env, CONST_STRING("QUERY_STRING"), con->uri.query->used ? con->uri.query->ptr : "");
32814         ssi_env_add(p->ssi_cgi_env, CONST_STRING("REQUEST_METHOD"), get_http_method_name(con->request.http_method));
32815         ssi_env_add(p->ssi_cgi_env, CONST_STRING("REDIRECT_STATUS"), "200");
32816         ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_PROTOCOL"), get_http_version_name(con->request.http_version));
32817 -       
32818 +
32819         ssi_env_add_request_headers(srv, con, p);
32820 -       
32821 +
32822         return 0;
32823  }
32824  
32825 -static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, 
32826 +static int process_ssi_stmt(server *srv, connection *con, plugin_data *p,
32827                             const char **l, size_t n) {
32828         size_t i, ssicmd = 0;
32829         char buf[255];
32830         buffer *b = NULL;
32831 -       
32832 -       struct { 
32833 +
32834 +       struct {
32835                 const char *var;
32836 -               enum { SSI_UNSET, SSI_ECHO, SSI_FSIZE, SSI_INCLUDE, SSI_FLASTMOD, 
32837 +               enum { SSI_UNSET, SSI_ECHO, SSI_FSIZE, SSI_INCLUDE, SSI_FLASTMOD,
32838                                 SSI_CONFIG, SSI_PRINTENV, SSI_SET, SSI_IF, SSI_ELIF,
32839                                 SSI_ELSE, SSI_ENDIF, SSI_EXEC } type;
32840         } ssicmds[] = {
32841 @@ -310,27 +311,27 @@
32842                 { "endif",    SSI_ENDIF },
32843                 { "else",     SSI_ELSE },
32844                 { "exec",     SSI_EXEC },
32845 -               
32846 +
32847                 { NULL, SSI_UNSET }
32848         };
32849 -       
32850 +
32851         for (i = 0; ssicmds[i].var; i++) {
32852                 if (0 == strcmp(l[1], ssicmds[i].var)) {
32853                         ssicmd = ssicmds[i].type;
32854                         break;
32855                 }
32856         }
32857 -       
32858 +
32859         switch(ssicmd) {
32860         case SSI_ECHO: {
32861                 /* echo */
32862                 int var = 0, enc = 0;
32863                 const char *var_val = NULL;
32864                 stat_cache_entry *sce = NULL;
32865 -               
32866 -               struct { 
32867 +
32868 +               struct {
32869                         const char *var;
32870 -                       enum { SSI_ECHO_UNSET, SSI_ECHO_DATE_GMT, SSI_ECHO_DATE_LOCAL, SSI_ECHO_DOCUMENT_NAME, SSI_ECHO_DOCUMENT_URI, 
32871 +                       enum { SSI_ECHO_UNSET, SSI_ECHO_DATE_GMT, SSI_ECHO_DATE_LOCAL, SSI_ECHO_DOCUMENT_NAME, SSI_ECHO_DOCUMENT_URI,
32872                                         SSI_ECHO_LAST_MODIFIED, SSI_ECHO_USER_NAME } type;
32873                 } echovars[] = {
32874                         { "DATE_GMT",      SSI_ECHO_DATE_GMT },
32875 @@ -339,27 +340,27 @@
32876                         { "DOCUMENT_URI",  SSI_ECHO_DOCUMENT_URI },
32877                         { "LAST_MODIFIED", SSI_ECHO_LAST_MODIFIED },
32878                         { "USER_NAME",     SSI_ECHO_USER_NAME },
32879 -                       
32880 +
32881                         { NULL, SSI_ECHO_UNSET }
32882                 };
32883 -               
32884 -               struct { 
32885 +
32886 +               struct {
32887                         const char *var;
32888                         enum { SSI_ENC_UNSET, SSI_ENC_URL, SSI_ENC_NONE, SSI_ENC_ENTITY } type;
32889                 } encvars[] = {
32890                         { "url",          SSI_ENC_URL },
32891                         { "none",         SSI_ENC_NONE },
32892                         { "entity",       SSI_ENC_ENTITY },
32893 -                       
32894 +
32895                         { NULL, SSI_ENC_UNSET }
32896                 };
32897 -               
32898 +
32899                 for (i = 2; i < n; i += 2) {
32900                         if (0 == strcmp(l[i], "var")) {
32901                                 int j;
32902 -                               
32903 +
32904                                 var_val = l[i+1];
32905 -                               
32906 +
32907                                 for (j = 0; echovars[j].var; j++) {
32908                                         if (0 == strcmp(l[i+1], echovars[j].var)) {
32909                                                 var = echovars[j].type;
32910 @@ -368,7 +369,7 @@
32911                                 }
32912                         } else if (0 == strcmp(l[i], "encoding")) {
32913                                 int j;
32914 -                               
32915 +
32916                                 for (j = 0; encvars[j].var; j++) {
32917                                         if (0 == strcmp(l[i+1], encvars[j].var)) {
32918                                                 enc = encvars[j].type;
32919 @@ -377,26 +378,26 @@
32920                                 }
32921                         } else {
32922                                 log_error_write(srv, __FILE__, __LINE__, "sss",
32923 -                                               "ssi: unknow attribute for ", 
32924 +                                               "ssi: unknow attribute for ",
32925                                                 l[1], l[i]);
32926                         }
32927                 }
32928 -               
32929 +
32930                 if (p->if_is_false) break;
32931 -               
32932 +
32933                 if (!var_val) {
32934                         log_error_write(srv, __FILE__, __LINE__, "sss",
32935 -                                       "ssi: ", 
32936 +                                       "ssi: ",
32937                                         l[1], "var is missing");
32938                         break;
32939                 }
32940  
32941                 stat_cache_get_entry(srv, con, con->physical.path, &sce);
32942 -               
32943 +
32944                 switch(var) {
32945                 case SSI_ECHO_USER_NAME: {
32946                         struct passwd *pw;
32947 -                       
32948 +
32949                         b = chunkqueue_get_append_buffer(con->write_queue);
32950  #ifdef HAVE_PWD_H
32951                         if (NULL == (pw = getpwuid(sce->st.st_uid))) {
32952 @@ -411,7 +412,7 @@
32953                 }
32954                 case SSI_ECHO_LAST_MODIFIED:    {
32955                         time_t t = sce->st.st_mtime;
32956 -                       
32957 +
32958                         b = chunkqueue_get_append_buffer(con->write_queue);
32959                         if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, localtime(&t))) {
32960                                 buffer_copy_string(b, "(none)");
32961 @@ -422,7 +423,7 @@
32962                 }
32963                 case SSI_ECHO_DATE_LOCAL: {
32964                         time_t t = time(NULL);
32965 -                       
32966 +
32967                         b = chunkqueue_get_append_buffer(con->write_queue);
32968                         if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, localtime(&t))) {
32969                                 buffer_copy_string(b, "(none)");
32970 @@ -433,7 +434,7 @@
32971                 }
32972                 case SSI_ECHO_DATE_GMT: {
32973                         time_t t = time(NULL);
32974 -                       
32975 +
32976                         b = chunkqueue_get_append_buffer(con->write_queue);
32977                         if (0 == strftime(buf, sizeof(buf), p->timefmt->ptr, gmtime(&t))) {
32978                                 buffer_copy_string(b, "(none)");
32979 @@ -444,7 +445,7 @@
32980                 }
32981                 case SSI_ECHO_DOCUMENT_NAME: {
32982                         char *sl;
32983 -                       
32984 +
32985                         b = chunkqueue_get_append_buffer(con->write_queue);
32986                         if (NULL == (sl = strrchr(con->physical.path->ptr, '/'))) {
32987                                 buffer_copy_string_buffer(b, con->physical.path);
32988 @@ -461,15 +462,15 @@
32989                 default: {
32990                         data_string *ds;
32991                         /* check if it is a cgi-var */
32992 -                       
32993 +
32994                         b = chunkqueue_get_append_buffer(con->write_queue);
32995 -                       
32996 +
32997                         if (NULL != (ds = (data_string *)array_get_element(p->ssi_cgi_env, var_val))) {
32998                                 buffer_copy_string_buffer(b, ds->value);
32999                         } else {
33000                                 buffer_copy_string(b, "(none)");
33001                         }
33002 -                       
33003 +
33004                         break;
33005                 }
33006                 }
33007 @@ -481,7 +482,7 @@
33008                 const char * file_path = NULL, *virt_path = NULL;
33009                 struct stat st;
33010                 char *sl;
33011 -               
33012 +
33013                 for (i = 2; i < n; i += 2) {
33014                         if (0 == strcmp(l[i], "file")) {
33015                                 file_path = l[i+1];
33016 @@ -489,28 +490,28 @@
33017                                 virt_path = l[i+1];
33018                         } else {
33019                                 log_error_write(srv, __FILE__, __LINE__, "sss",
33020 -                                               "ssi: unknow attribute for ", 
33021 +                                               "ssi: unknow attribute for ",
33022                                                 l[1], l[i]);
33023                         }
33024                 }
33025 -               
33026 +
33027                 if (!file_path && !virt_path) {
33028                         log_error_write(srv, __FILE__, __LINE__, "sss",
33029 -                                       "ssi: ", 
33030 +                                       "ssi: ",
33031                                         l[1], "file or virtual are missing");
33032                         break;
33033                 }
33034 -               
33035 +
33036                 if (file_path && virt_path) {
33037                         log_error_write(srv, __FILE__, __LINE__, "sss",
33038 -                                       "ssi: ", 
33039 +                                       "ssi: ",
33040                                         l[1], "only one of file and virtual is allowed here");
33041                         break;
33042                 }
33043 -               
33044 -               
33045 +
33046 +
33047                 if (p->if_is_false) break;
33048 -               
33049 +
33050                 if (file_path) {
33051                         /* current doc-root */
33052                         if (NULL == (sl = strrchr(con->physical.path->ptr, '/'))) {
33053 @@ -519,46 +520,46 @@
33054                                 buffer_copy_string_len(p->stat_fn, con->physical.path->ptr, sl - con->physical.path->ptr + 1);
33055                         }
33056  
33057 -                       buffer_copy_string(srv->tmp_buf, file_path); 
33058 +                       buffer_copy_string(srv->tmp_buf, file_path);
33059                         buffer_urldecode_path(srv->tmp_buf);
33060 -                       buffer_path_simplify(srv->tmp_buf, srv->tmp_buf); 
33061 -                       buffer_append_string_buffer(p->stat_fn, srv->tmp_buf); 
33062 +                       buffer_path_simplify(srv->tmp_buf, srv->tmp_buf);
33063 +                       buffer_append_string_buffer(p->stat_fn, srv->tmp_buf);
33064                 } else {
33065                         /* virtual */
33066 -                       
33067 +
33068                         if (virt_path[0] == '/') {
33069                                 buffer_copy_string(p->stat_fn, virt_path);
33070                         } else {
33071                                 /* there is always a / */
33072                                 sl = strrchr(con->uri.path->ptr, '/');
33073 -                               
33074 +
33075                                 buffer_copy_string_len(p->stat_fn, con->uri.path->ptr, sl - con->uri.path->ptr + 1);
33076                                 buffer_append_string(p->stat_fn, virt_path);
33077                         }
33078 -                       
33079 +
33080                         buffer_urldecode_path(p->stat_fn);
33081                         buffer_path_simplify(srv->tmp_buf, p->stat_fn);
33082 -                       
33083 +
33084                         /* we have an uri */
33085 -                       
33086 +
33087                         buffer_copy_string_buffer(p->stat_fn, con->physical.doc_root);
33088                         buffer_append_string_buffer(p->stat_fn, srv->tmp_buf);
33089                 }
33090 -               
33091 +
33092                 if (0 == stat(p->stat_fn->ptr, &st)) {
33093                         time_t t = st.st_mtime;
33094 -                       
33095 +
33096                         switch (ssicmd) {
33097                         case SSI_FSIZE:
33098                                 b = chunkqueue_get_append_buffer(con->write_queue);
33099                                 if (p->sizefmt) {
33100                                         int j = 0;
33101                                         const char *abr[] = { " B", " kB", " MB", " GB", " TB", NULL };
33102 -                                       
33103 +
33104                                         off_t s = st.st_size;
33105 -                                       
33106 +
33107                                         for (j = 0; s > 1024 && abr[j+1]; s /= 1024, j++);
33108 -                                       
33109 +
33110                                         buffer_copy_off_t(b, s);
33111                                         buffer_append_string(b, abr[j]);
33112                                 } else {
33113 @@ -579,7 +580,7 @@
33114                         }
33115                 } else {
33116                         log_error_write(srv, __FILE__, __LINE__, "sbs",
33117 -                                       "ssi: stating failed ", 
33118 +                                       "ssi: stating failed ",
33119                                         p->stat_fn, strerror(errno));
33120                 }
33121                 break;
33122 @@ -593,33 +594,33 @@
33123                                 val = l[i+1];
33124                         } else {
33125                                 log_error_write(srv, __FILE__, __LINE__, "sss",
33126 -                                               "ssi: unknow attribute for ", 
33127 +                                               "ssi: unknow attribute for ",
33128                                                 l[1], l[i]);
33129                         }
33130                 }
33131 -               
33132 +
33133                 if (p->if_is_false) break;
33134 -               
33135 +
33136                 if (key && val) {
33137                         data_string *ds;
33138 -                       
33139 +
33140                         if (NULL == (ds = (data_string *)array_get_unused_element(p->ssi_vars, TYPE_STRING))) {
33141                                 ds = data_string_init();
33142                         }
33143                         buffer_copy_string(ds->key,   key);
33144                         buffer_copy_string(ds->value, val);
33145 -                       
33146 +
33147                         array_insert_unique(p->ssi_vars, (data_unset *)ds);
33148                 } else {
33149                         log_error_write(srv, __FILE__, __LINE__, "sss",
33150 -                                       "ssi: var and value have to be set in", 
33151 +                                       "ssi: var and value have to be set in",
33152                                         l[0], l[1]);
33153                 }
33154                 break;
33155         }
33156 -       case SSI_CONFIG: 
33157 +       case SSI_CONFIG:
33158                 if (p->if_is_false) break;
33159 -               
33160 +
33161                 for (i = 2; i < n; i += 2) {
33162                         if (0 == strcmp(l[i], "timefmt")) {
33163                                 buffer_copy_string(p->timefmt, l[i+1]);
33164 @@ -632,63 +633,65 @@
33165                                         log_error_write(srv, __FILE__, __LINE__, "sssss",
33166                                                         "ssi: unknow value for attribute '",
33167                                                         l[i],
33168 -                                                       "' for ", 
33169 +                                                       "' for ",
33170                                                         l[1], l[i+1]);
33171                                 }
33172                         } else {
33173                                 log_error_write(srv, __FILE__, __LINE__, "sss",
33174 -                                               "ssi: unknow attribute for ", 
33175 +                                               "ssi: unknow attribute for ",
33176                                                 l[1], l[i]);
33177                         }
33178                 }
33179                 break;
33180         case SSI_PRINTENV:
33181                 if (p->if_is_false) break;
33182 -               
33183 +
33184                 b = chunkqueue_get_append_buffer(con->write_queue);
33185                 buffer_copy_string(b, "<pre>");
33186                 for (i = 0; i < p->ssi_vars->used; i++) {
33187                         data_string *ds = (data_string *)p->ssi_vars->data[p->ssi_vars->sorted[i]];
33188 -                       
33189 +
33190                         buffer_append_string_buffer(b, ds->key);
33191                         buffer_append_string(b, ": ");
33192                         buffer_append_string_buffer(b, ds->value);
33193                         buffer_append_string(b, "<br />");
33194 -                                       
33195 +
33196                 }
33197                 buffer_append_string(b, "</pre>");
33198 -               
33199 +
33200                 break;
33201         case SSI_EXEC: {
33202 +#ifndef _WIN32
33203 +
33204                 const char *cmd = NULL;
33205                 pid_t pid;
33206                 int from_exec_fds[2];
33207 -               
33208 +
33209                 for (i = 2; i < n; i += 2) {
33210                         if (0 == strcmp(l[i], "cmd")) {
33211                                 cmd = l[i+1];
33212                         } else {
33213                                 log_error_write(srv, __FILE__, __LINE__, "sss",
33214 -                                               "ssi: unknow attribute for ", 
33215 +                                               "ssi: unknow attribute for ",
33216                                                 l[1], l[i]);
33217                         }
33218                 }
33219 -               
33220 +
33221                 if (p->if_is_false) break;
33222 -               
33223 +
33224                 /* create a return pipe and send output to the html-page
33225 -                * 
33226 -                * as exec is assumed evil it is implemented synchronously 
33227 +                *
33228 +                * as exec is assumed evil it is implemented synchronously
33229                  */
33230 -               
33231 +
33232                 if (!cmd) break;
33233 -#ifdef HAVE_FORK       
33234 +
33235                 if (pipe(from_exec_fds)) {
33236 -                       log_error_write(srv, __FILE__, __LINE__, "ss", 
33237 +                       log_error_write(srv, __FILE__, __LINE__, "ss",
33238                                         "pipe failed: ", strerror(errno));
33239                         return -1;
33240                 }
33241 -       
33242 +
33243                 /* fork, execve */
33244                 switch (pid = fork()) {
33245                 case 0: {
33246 @@ -698,14 +701,14 @@
33247                         close(from_exec_fds[1]);
33248                         /* not needed */
33249                         close(from_exec_fds[0]);
33250 -                       
33251 +
33252                         /* close stdin */
33253                         close(STDIN_FILENO);
33254 -               
33255 +
33256                         execl("/bin/sh", "sh", "-c", cmd, NULL);
33257 -                       
33258 +
33259                         log_error_write(srv, __FILE__, __LINE__, "sss", "spawing exec failed:", strerror(errno), cmd);
33260 -               
33261 +
33262                         /* */
33263                         SEGFAULT();
33264                         break;
33265 @@ -718,9 +721,9 @@
33266                         /* father */
33267                         int status;
33268                         ssize_t r;
33269 -                       
33270 +
33271                         close(from_exec_fds[1]);
33272 -                       
33273 +
33274                         /* wait for the client to end */
33275                         if (-1 == waitpid(pid, &status, 0)) {
33276                                 log_error_write(srv, __FILE__, __LINE__, "ss", "waitpid failed:", strerror(errno));
33277 @@ -730,7 +733,7 @@
33278  
33279                                 while(1) {
33280                                         if (ioctl(from_exec_fds[0], FIONREAD, &toread)) {
33281 -                                               log_error_write(srv, __FILE__, __LINE__, "s", 
33282 +                                               log_error_write(srv, __FILE__, __LINE__, "s",
33283                                                         "unexpected end-of-file (perhaps the ssi-exec process died)");
33284                                                 return -1;
33285                                         }
33286 @@ -738,10 +741,10 @@
33287                                         if (toread > 0) {
33288                                                 b = chunkqueue_get_append_buffer(con->write_queue);
33289  
33290 -                                               buffer_prepare_copy(b, toread + 1); 
33291 +                                               buffer_prepare_copy(b, toread + 1);
33292  
33293                                                 if ((r = read(from_exec_fds[0], b->ptr, b->size - 1)) < 0) {
33294 -                                                       /* read failed */ 
33295 +                                                       /* read failed */
33296                                                         break;
33297                                                 } else {
33298                                                         b->used = r;
33299 @@ -755,59 +758,58 @@
33300                                 log_error_write(srv, __FILE__, __LINE__, "s", "process exited abnormally");
33301                         }
33302                         close(from_exec_fds[0]);
33303 -                       
33304 +
33305                         break;
33306                 }
33307                 }
33308  #else
33309 -
33310                 return -1;
33311  #endif
33312 -               
33313 +
33314                 break;
33315         }
33316         case SSI_IF: {
33317                 const char *expr = NULL;
33318 -               
33319 +
33320                 for (i = 2; i < n; i += 2) {
33321                         if (0 == strcmp(l[i], "expr")) {
33322                                 expr = l[i+1];
33323                         } else {
33324                                 log_error_write(srv, __FILE__, __LINE__, "sss",
33325 -                                               "ssi: unknow attribute for ", 
33326 +                                               "ssi: unknow attribute for ",
33327                                                 l[1], l[i]);
33328                         }
33329                 }
33330 -               
33331 +
33332                 if (!expr) {
33333                         log_error_write(srv, __FILE__, __LINE__, "sss",
33334 -                                       "ssi: ", 
33335 +                                       "ssi: ",
33336                                         l[1], "expr missing");
33337                         break;
33338                 }
33339 -               
33340 +
33341                 if ((!p->if_is_false) &&
33342 -                   ((p->if_is_false_level == 0) || 
33343 +                   ((p->if_is_false_level == 0) ||
33344                      (p->if_level < p->if_is_false_level))) {
33345                         switch (ssi_eval_expr(srv, con, p, expr)) {
33346                         case -1:
33347 -                       case 0: 
33348 -                               p->if_is_false = 1; 
33349 +                       case 0:
33350 +                               p->if_is_false = 1;
33351                                 p->if_is_false_level = p->if_level;
33352                                 break;
33353 -                       case 1: 
33354 -                               p->if_is_false = 0; 
33355 +                       case 1:
33356 +                               p->if_is_false = 0;
33357                                 break;
33358                         }
33359                 }
33360 -               
33361 +
33362                 p->if_level++;
33363 -               
33364 +
33365                 break;
33366         }
33367         case SSI_ELSE:
33368                 p->if_level--;
33369 -               
33370 +
33371                 if (p->if_is_false) {
33372                         if ((p->if_level == p->if_is_false_level) &&
33373                             (p->if_is_false_endif == 0)) {
33374 @@ -815,11 +817,11 @@
33375                         }
33376                 } else {
33377                         p->if_is_false = 1;
33378 -                       
33379 +
33380                         p->if_is_false_level = p->if_level;
33381                 }
33382                 p->if_level++;
33383 -               
33384 +
33385                 break;
33386         case SSI_ELIF: {
33387                 const char *expr = NULL;
33388 @@ -828,52 +830,52 @@
33389                                 expr = l[i+1];
33390                         } else {
33391                                 log_error_write(srv, __FILE__, __LINE__, "sss",
33392 -                                               "ssi: unknow attribute for ", 
33393 +                                               "ssi: unknow attribute for ",
33394                                                 l[1], l[i]);
33395                         }
33396                 }
33397 -               
33398 +
33399                 if (!expr) {
33400                         log_error_write(srv, __FILE__, __LINE__, "sss",
33401 -                                       "ssi: ", 
33402 +                                       "ssi: ",
33403                                         l[1], "expr missing");
33404                         break;
33405                 }
33406 -               
33407 +
33408                 p->if_level--;
33409 -               
33410 +
33411                 if (p->if_level == p->if_is_false_level) {
33412                         if ((p->if_is_false) &&
33413                             (p->if_is_false_endif == 0)) {
33414                                 switch (ssi_eval_expr(srv, con, p, expr)) {
33415                                 case -1:
33416 -                               case 0: 
33417 -                                       p->if_is_false = 1; 
33418 +                               case 0:
33419 +                                       p->if_is_false = 1;
33420                                         p->if_is_false_level = p->if_level;
33421                                         break;
33422 -                               case 1: 
33423 -                                       p->if_is_false = 0; 
33424 +                               case 1:
33425 +                                       p->if_is_false = 0;
33426                                         break;
33427                                 }
33428                         } else {
33429 -                               p->if_is_false = 1; 
33430 +                               p->if_is_false = 1;
33431                                 p->if_is_false_level = p->if_level;
33432                                 p->if_is_false_endif = 1;
33433                         }
33434                 }
33435 -               
33436 +
33437                 p->if_level++;
33438 -               
33439 +
33440                 break;
33441         }
33442         case SSI_ENDIF:
33443                 p->if_level--;
33444 -               
33445 +
33446                 if (p->if_level == p->if_is_false_level) {
33447                         p->if_is_false = 0;
33448                         p->if_is_false_endif = 0;
33449                 }
33450 -                       
33451 +
33452                 break;
33453         default:
33454                 log_error_write(srv, __FILE__, __LINE__, "ss",
33455 @@ -881,41 +883,41 @@
33456                                 l[1]);
33457                 break;
33458         }
33459 -       
33460 +
33461         return 0;
33462 -       
33463 +
33464  }
33465  
33466  static int mod_ssi_handle_request(server *srv, connection *con, plugin_data *p) {
33467         stream s;
33468  #ifdef  HAVE_PCRE_H
33469         int i, n;
33470 -       
33471 +
33472  #define N 10
33473         int ovec[N * 3];
33474  #endif
33475 -       
33476 +
33477         /* get a stream to the file */
33478 -       
33479 +
33480         array_reset(p->ssi_vars);
33481         array_reset(p->ssi_cgi_env);
33482         buffer_copy_string(p->timefmt, "%a, %d %b %Y %H:%M:%S %Z");
33483         p->sizefmt = 0;
33484         build_ssi_cgi_vars(srv, con, p);
33485         p->if_is_false = 0;
33486 -       
33487 +
33488         if (-1 == stream_open(&s, con->physical.path)) {
33489                 log_error_write(srv, __FILE__, __LINE__, "sb",
33490                                 "stream-open: ", con->physical.path);
33491                 return -1;
33492         }
33493 -       
33494 -       
33495 +
33496 +
33497         /**
33498 -        * <!--#element attribute=value attribute=value ... --> 
33499 -        * 
33500 +        * <!--#element attribute=value attribute=value ... -->
33501 +        *
33502          * config       DONE
33503 -        *   errmsg     -- missing 
33504 +        *   errmsg     -- missing
33505          *   sizefmt    DONE
33506          *   timefmt    DONE
33507          * echo         DONE
33508 @@ -937,13 +939,13 @@
33509          * set          DONE
33510          *   var        DONE
33511          *   value      DONE
33512 -        * 
33513 +        *
33514          * if           DONE
33515          * elif         DONE
33516          * else         DONE
33517          * endif        DONE
33518 -        * 
33519 -        * 
33520 +        *
33521 +        *
33522          * expressions
33523          * AND, OR      DONE
33524          * comp         DONE
33525 @@ -951,118 +953,115 @@
33526          * $...         DONE
33527          * '...'        DONE
33528          * ( ... )      DONE
33529 -        * 
33530 -        * 
33531 -        * 
33532 +        *
33533 +        *
33534 +        *
33535          * ** all DONE **
33536 -        * DATE_GMT 
33537 -        *   The current date in Greenwich Mean Time. 
33538 -        * DATE_LOCAL 
33539 -        *   The current date in the local time zone. 
33540 -        * DOCUMENT_NAME 
33541 -        *   The filename (excluding directories) of the document requested by the user. 
33542 -        * DOCUMENT_URI 
33543 -        *   The (%-decoded) URL path of the document requested by the user. Note that in the case of nested include files, this is not then URL for the current document. 
33544 -        * LAST_MODIFIED 
33545 -        *   The last modification date of the document requested by the user. 
33546 -        * USER_NAME 
33547 +        * DATE_GMT
33548 +        *   The current date in Greenwich Mean Time.
33549 +        * DATE_LOCAL
33550 +        *   The current date in the local time zone.
33551 +        * DOCUMENT_NAME
33552 +        *   The filename (excluding directories) of the document requested by the user.
33553 +        * DOCUMENT_URI
33554 +        *   The (%-decoded) URL path of the document requested by the user. Note that in the case of nested include files, this is not then URL for the current document.
33555 +        * LAST_MODIFIED
33556 +        *   The last modification date of the document requested by the user.
33557 +        * USER_NAME
33558          *   Contains the owner of the file which included it.
33559 -        * 
33560 +        *
33561          */
33562 -#ifdef HAVE_PCRE_H     
33563 +#ifdef HAVE_PCRE_H
33564         for (i = 0; (n = pcre_exec(p->ssi_regex, NULL, s.start, s.size, i, 0, ovec, N * 3)) > 0; i = ovec[1]) {
33565                 const char **l;
33566                 /* take everything from last offset to current match pos */
33567 -               
33568 +
33569                 if (!p->if_is_false) chunkqueue_append_file(con->write_queue, con->physical.path, i, ovec[0] - i);
33570 -               
33571 +
33572                 pcre_get_substring_list(s.start, ovec, n, &l);
33573                 process_ssi_stmt(srv, con, p, l, n);
33574                 pcre_free_substring_list(l);
33575         }
33576 -       
33577 +
33578         switch(n) {
33579         case PCRE_ERROR_NOMATCH:
33580                 /* copy everything/the rest */
33581                 chunkqueue_append_file(con->write_queue, con->physical.path, i, s.size - i);
33582 -               
33583 +
33584                 break;
33585         default:
33586                 log_error_write(srv, __FILE__, __LINE__, "sd",
33587                                 "execution error while matching: ", n);
33588                 break;
33589         }
33590 -#endif 
33591 -       
33592 -       
33593 +#endif
33594 +
33595 +
33596         stream_close(&s);
33597 -       
33598 +
33599         con->file_started  = 1;
33600         con->file_finished = 1;
33601 -       
33602 +
33603         response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
33604 -       
33605 +
33606         /* reset physical.path */
33607         buffer_reset(con->physical.path);
33608 -       
33609 +
33610         return 0;
33611  }
33612  
33613 -#define PATCH(x) \
33614 -       p->conf.x = s->x;
33615  static int mod_ssi_patch_connection(server *srv, connection *con, plugin_data *p) {
33616         size_t i, j;
33617         plugin_config *s = p->config_storage[0];
33618 -       
33619 -       PATCH(ssi_extension);
33620 -       
33621 +
33622 +       PATCH_OPTION(ssi_extension);
33623 +
33624         /* skip the first, the global context */
33625         for (i = 1; i < srv->config_context->used; i++) {
33626                 data_config *dc = (data_config *)srv->config_context->data[i];
33627                 s = p->config_storage[i];
33628 -               
33629 +
33630                 /* condition didn't match */
33631                 if (!config_check_cond(srv, con, dc)) continue;
33632 -               
33633 +
33634                 /* merge config */
33635                 for (j = 0; j < dc->value->used; j++) {
33636                         data_unset *du = dc->value->data[j];
33637 -                       
33638 +
33639                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssi.extension"))) {
33640 -                               PATCH(ssi_extension);
33641 +                               PATCH_OPTION(ssi_extension);
33642                         }
33643                 }
33644         }
33645 -       
33646 +
33647         return 0;
33648  }
33649 -#undef PATCH
33650  
33651  URIHANDLER_FUNC(mod_ssi_physical_path) {
33652         plugin_data *p = p_d;
33653         size_t k;
33654 -       
33655 +
33656         if (con->physical.path->used == 0) return HANDLER_GO_ON;
33657 -       
33658 +
33659         mod_ssi_patch_connection(srv, con, p);
33660 -       
33661 +
33662         for (k = 0; k < p->conf.ssi_extension->used; k++) {
33663                 data_string *ds = (data_string *)p->conf.ssi_extension->data[k];
33664 -               
33665 +
33666                 if (ds->value->used == 0) continue;
33667 -               
33668 +
33669                 if (buffer_is_equal_right_len(con->physical.path, ds->value, ds->value->used - 1)) {
33670                         /* handle ssi-request */
33671 -                       
33672 +
33673                         if (mod_ssi_handle_request(srv, con, p)) {
33674                                 /* on error */
33675                                 con->http_status = 500;
33676                         }
33677 -                       
33678 +
33679                         return HANDLER_FINISHED;
33680                 }
33681         }
33682 -       
33683 +
33684         /* not found */
33685         return HANDLER_GO_ON;
33686  }
33687 @@ -1072,13 +1071,13 @@
33688  int mod_ssi_plugin_init(plugin *p) {
33689         p->version     = LIGHTTPD_VERSION_ID;
33690         p->name        = buffer_init_string("ssi");
33691 -       
33692 +
33693         p->init        = mod_ssi_init;
33694         p->handle_subrequest_start = mod_ssi_physical_path;
33695         p->set_defaults  = mod_ssi_set_defaults;
33696         p->cleanup     = mod_ssi_free;
33697 -       
33698 +
33699         p->data        = NULL;
33700 -       
33701 +
33702         return 0;
33703  }
33704
33705 Property changes on: src/mod_ssi.c
33706 ___________________________________________________________________
33707 Name: svn:eol-style
33708    + native
33709
33710 Index: src/spawn-fcgi.c
33711 ===================================================================
33712 --- src/spawn-fcgi.c    (.../tags/lighttpd-1.4.11)      (revision 1159)
33713 +++ src/spawn-fcgi.c    (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
33714 @@ -1,19 +1,16 @@
33715  #include <sys/types.h>
33716 -#include <sys/time.h>
33717  #include <sys/stat.h>
33718  
33719  #include <stdlib.h>
33720  #include <string.h>
33721  #include <errno.h>
33722  #include <stdio.h>
33723 -#include <unistd.h>
33724  #include <fcntl.h>
33725 -
33726 +#include <time.h>
33727  #ifdef HAVE_CONFIG_H
33728  #include "config.h"
33729  #endif
33730  
33731 -
33732  #ifdef HAVE_PWD_H
33733  #include <grp.h>
33734  #include <pwd.h>
33735 @@ -30,6 +27,7 @@
33736  #endif
33737  
33738  #include "sys-socket.h"
33739 +#include "sys-files.h"
33740  
33741  #ifdef HAVE_SYS_WAIT_H
33742  #include <sys/wait.h>
33743 @@ -45,28 +43,28 @@
33744         int fcgi_fd;
33745         int socket_type, status;
33746         struct timeval tv = { 0, 100 * 1000 };
33747 -       
33748 +
33749         struct sockaddr_un fcgi_addr_un;
33750         struct sockaddr_in fcgi_addr_in;
33751         struct sockaddr *fcgi_addr;
33752 -       
33753 +
33754         socklen_t servlen;
33755 -       
33756 +
33757         if (child_count < 2) {
33758                 child_count = 5;
33759         }
33760 -       
33761 +
33762         if (child_count > 256) {
33763                 child_count = 256;
33764         }
33765 -       
33766 -       
33767 +
33768 +
33769         if (unixsocket) {
33770                 memset(&fcgi_addr, 0, sizeof(fcgi_addr));
33771 -               
33772 +
33773                 fcgi_addr_un.sun_family = AF_UNIX;
33774                 strcpy(fcgi_addr_un.sun_path, unixsocket);
33775 -               
33776 +
33777  #ifdef SUN_LEN
33778                 servlen = SUN_LEN(&fcgi_addr_un);
33779  #else
33780 @@ -84,50 +82,50 @@
33781                  }
33782                 fcgi_addr_in.sin_port = htons(port);
33783                 servlen = sizeof(fcgi_addr_in);
33784 -               
33785 +
33786                 socket_type = AF_INET;
33787                 fcgi_addr = (struct sockaddr *) &fcgi_addr_in;
33788         }
33789 -       
33790 +
33791         if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
33792 -               fprintf(stderr, "%s.%d\n", 
33793 +               fprintf(stderr, "%s.%d\n",
33794                         __FILE__, __LINE__);
33795                 return -1;
33796         }
33797 -       
33798 +
33799         if (-1 == connect(fcgi_fd, fcgi_addr, servlen)) {
33800                 /* server is not up, spawn in  */
33801                 pid_t child;
33802                 int val;
33803 -               
33804 +
33805                 if (unixsocket) unlink(unixsocket);
33806 -               
33807 +
33808                 close(fcgi_fd);
33809 -               
33810 +
33811                 /* reopen socket */
33812                 if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
33813 -                       fprintf(stderr, "%s.%d\n", 
33814 +                       fprintf(stderr, "%s.%d\n",
33815                                 __FILE__, __LINE__);
33816                         return -1;
33817                 }
33818  
33819                 val = 1;
33820                 if (setsockopt(fcgi_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
33821 -                       fprintf(stderr, "%s.%d\n", 
33822 +                       fprintf(stderr, "%s.%d\n",
33823                                 __FILE__, __LINE__);
33824                         return -1;
33825                 }
33826  
33827                 /* create socket */
33828                 if (-1 == bind(fcgi_fd, fcgi_addr, servlen)) {
33829 -                       fprintf(stderr, "%s.%d: bind failed: %s\n", 
33830 +                       fprintf(stderr, "%s.%d: bind failed: %s\n",
33831                                 __FILE__, __LINE__,
33832                                 strerror(errno));
33833                         return -1;
33834                 }
33835 -               
33836 +
33837                 if (-1 == listen(fcgi_fd, 1024)) {
33838 -                       fprintf(stderr, "%s.%d: fd = -1\n", 
33839 +                       fprintf(stderr, "%s.%d: fd = -1\n",
33840                                 __FILE__, __LINE__);
33841                         return -1;
33842                 }
33843 @@ -137,42 +135,45 @@
33844                 } else {
33845                         child = 0;
33846                 }
33847 -               
33848 +
33849                 switch (child) {
33850                 case 0: {
33851                         char cgi_childs[64];
33852                         char *b;
33853 -                       
33854 +
33855                         int i = 0;
33856 -                       
33857 +
33858 +                       /* loose control terminal */
33859 +                       setsid();
33860 +
33861                         /* is save as we limit to 256 childs */
33862                         sprintf(cgi_childs, "PHP_FCGI_CHILDREN=%d", child_count);
33863 -                       
33864 +
33865                         if(fcgi_fd != FCGI_LISTENSOCK_FILENO) {
33866                                 close(FCGI_LISTENSOCK_FILENO);
33867                                 dup2(fcgi_fd, FCGI_LISTENSOCK_FILENO);
33868                                 close(fcgi_fd);
33869                         }
33870 -                       
33871 +
33872                         /* we don't need the client socket */
33873                         for (i = 3; i < 256; i++) {
33874                                 close(i);
33875                         }
33876 -                       
33877 +
33878                         /* create environment */
33879 -                       
33880 +
33881                         putenv(cgi_childs);
33882 -                       
33883 +
33884                         /* fork and replace shell */
33885                         b = malloc(strlen("exec ") + strlen(appPath) + 1);
33886                         strcpy(b, "exec ");
33887                         strcat(b, appPath);
33888 -                       
33889 +
33890                         /* exec the cgi */
33891                         execl("/bin/sh", "sh", "-c", b, NULL);
33892 -                       
33893 +
33894                         exit(errno);
33895 -                       
33896 +
33897                         break;
33898                 }
33899                 case -1:
33900 @@ -180,47 +181,47 @@
33901                         break;
33902                 default:
33903                         /* father */
33904 -                       
33905 +
33906                         /* wait */
33907                         select(0, NULL, NULL, NULL, &tv);
33908 -                       
33909 +
33910                         switch (waitpid(child, &status, WNOHANG)) {
33911                         case 0:
33912 -                               fprintf(stderr, "%s.%d: child spawned successfully: PID: %d\n", 
33913 +                               fprintf(stderr, "%s.%d: child spawned successfully: PID: %d\n",
33914                                         __FILE__, __LINE__,
33915                                         child);
33916 -                               
33917 +
33918                                 /* write pid file */
33919                                 if (pid_fd != -1) {
33920                                         /* assume a 32bit pid_t */
33921                                         char pidbuf[12];
33922 -                                       
33923 +
33924                                         snprintf(pidbuf, sizeof(pidbuf) - 1, "%d", child);
33925 -                                       
33926 +
33927                                         write(pid_fd, pidbuf, strlen(pidbuf));
33928                                         close(pid_fd);
33929                                         pid_fd = -1;
33930                                 }
33931 -                               
33932 +
33933                                 break;
33934                         case -1:
33935                                 break;
33936                         default:
33937                                 if (WIFEXITED(status)) {
33938 -                                       fprintf(stderr, "%s.%d: child exited with: %d, %s\n", 
33939 +                                       fprintf(stderr, "%s.%d: child exited with: %d, %s\n",
33940                                                 __FILE__, __LINE__,
33941                                                 WEXITSTATUS(status), strerror(WEXITSTATUS(status)));
33942                                 } else if (WIFSIGNALED(status)) {
33943 -                                       fprintf(stderr, "%s.%d: child signaled: %d\n", 
33944 +                                       fprintf(stderr, "%s.%d: child signaled: %d\n",
33945                                                 __FILE__, __LINE__,
33946                                                 WTERMSIG(status));
33947                                 } else {
33948 -                                       fprintf(stderr, "%s.%d: child died somehow: %d\n", 
33949 +                                       fprintf(stderr, "%s.%d: child died somehow: %d\n",
33950                                                 __FILE__, __LINE__,
33951                                                 status);
33952                                 }
33953                         }
33954 -                               
33955 +
33956                         break;
33957                 }
33958         } else {
33959 @@ -228,16 +229,16 @@
33960                         __FILE__, __LINE__);
33961                 return -1;
33962         }
33963 -       
33964 +
33965         close(fcgi_fd);
33966 -       
33967 +
33968         return 0;
33969  }
33970  
33971  
33972  void show_version () {
33973         char *b = "spawn-fcgi" "-" PACKAGE_VERSION \
33974 -" - spawns fastcgi processes\n" 
33975 +" - spawns fastcgi processes\n"
33976  ;
33977         write(1, b, strlen(b));
33978  }
33979 @@ -265,7 +266,7 @@
33980  
33981  
33982  int main(int argc, char **argv) {
33983 -       char *fcgi_app = NULL, *changeroot = NULL, *username = NULL, 
33984 +       char *fcgi_app = NULL, *changeroot = NULL, *username = NULL,
33985                 *groupname = NULL, *unixsocket = NULL, *pid_file = NULL,
33986                  *addr = NULL;
33987         unsigned short port = 0;
33988 @@ -273,9 +274,9 @@
33989         int i_am_root, o;
33990         int pid_fd = -1;
33991         int nofork = 0;
33992 -       
33993 +
33994         i_am_root = (getuid() == 0);
33995 -       
33996 +
33997         while(-1 != (o = getopt(argc, argv, "c:f:g:hna:p:u:vC:s:P:"))) {
33998                 switch(o) {
33999                 case 'f': fcgi_app = optarg; break;
34000 @@ -290,137 +291,137 @@
34001                 case 'P': pid_file = optarg; /* PID file */ break;
34002                 case 'v': show_version(); return 0;
34003                 case 'h': show_help(); return 0;
34004 -               default: 
34005 +               default:
34006                         show_help();
34007                         return -1;
34008                 }
34009         }
34010 -       
34011 +
34012         if (fcgi_app == NULL || (port == 0 && unixsocket == NULL)) {
34013                 show_help();
34014                 return -1;
34015         }
34016 -           
34017 +
34018         if (unixsocket && port) {
34019 -               fprintf(stderr, "%s.%d: %s\n", 
34020 +               fprintf(stderr, "%s.%d: %s\n",
34021                         __FILE__, __LINE__,
34022                         "either a unix domain socket or a tcp-port, but not both\n");
34023 -               
34024 +
34025                 return -1;
34026         }
34027 -       
34028 +
34029         if (unixsocket && strlen(unixsocket) > UNIX_PATH_MAX - 1) {
34030 -               fprintf(stderr, "%s.%d: %s\n", 
34031 +               fprintf(stderr, "%s.%d: %s\n",
34032                         __FILE__, __LINE__,
34033                         "path of the unix socket is too long\n");
34034 -               
34035 +
34036                 return -1;
34037         }
34038  
34039         /* UID handling */
34040         if (!i_am_root && (geteuid() == 0 || getegid() == 0)) {
34041                 /* we are setuid-root */
34042 -               
34043 -               fprintf(stderr, "%s.%d: %s\n", 
34044 +
34045 +               fprintf(stderr, "%s.%d: %s\n",
34046                         __FILE__, __LINE__,
34047                         "Are you nuts ? Don't apply a SUID bit to this binary\n");
34048 -               
34049 +
34050                 return -1;
34051         }
34052 -       
34053 -       if (pid_file && 
34054 +
34055 +       if (pid_file &&
34056             (-1 == (pid_fd = open(pid_file, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)))) {
34057                 struct stat st;
34058                 if (errno != EEXIST) {
34059 -                       fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n", 
34060 +                       fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n",
34061                                 __FILE__, __LINE__,
34062                                 pid_file, strerror(errno));
34063 -                       
34064 +
34065                         return -1;
34066                 }
34067 -               
34068 +
34069                 /* ok, file exists */
34070 -               
34071 +
34072                 if (0 != stat(pid_file, &st)) {
34073 -                       fprintf(stderr, "%s.%d: stating pid-file '%s' failed: %s\n", 
34074 +                       fprintf(stderr, "%s.%d: stating pid-file '%s' failed: %s\n",
34075                                 __FILE__, __LINE__,
34076                                 pid_file, strerror(errno));
34077 -                       
34078 +
34079                         return -1;
34080                 }
34081 -               
34082 +
34083                 /* is it a regular file ? */
34084 -               
34085 +
34086                 if (!S_ISREG(st.st_mode)) {
34087 -                       fprintf(stderr, "%s.%d: pid-file exists and isn't regular file: '%s'\n", 
34088 +                       fprintf(stderr, "%s.%d: pid-file exists and isn't regular file: '%s'\n",
34089                                 __FILE__, __LINE__,
34090                                 pid_file);
34091 -                       
34092 +
34093                         return -1;
34094                 }
34095 -               
34096 +
34097                 if (-1 == (pid_fd = open(pid_file, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
34098 -                       fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n", 
34099 +                       fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n",
34100                                 __FILE__, __LINE__,
34101                                 pid_file, strerror(errno));
34102 -                       
34103 +
34104                         return -1;
34105                 }
34106         }
34107 -       
34108 +
34109         if (i_am_root) {
34110                 struct group *grp = NULL;
34111                 struct passwd *pwd = NULL;
34112 -               
34113 +
34114                 /* set user and group */
34115 -               
34116 +
34117                 if (username) {
34118                         if (NULL == (pwd = getpwnam(username))) {
34119 -                               fprintf(stderr, "%s.%d: %s, %s\n", 
34120 +                               fprintf(stderr, "%s.%d: %s, %s\n",
34121                                         __FILE__, __LINE__,
34122                                         "can't find username", username);
34123                                 return -1;
34124                         }
34125 -                       
34126 +
34127                         if (pwd->pw_uid == 0) {
34128 -                               fprintf(stderr, "%s.%d: %s\n", 
34129 +                               fprintf(stderr, "%s.%d: %s\n",
34130                                         __FILE__, __LINE__,
34131                                         "I will not set uid to 0\n");
34132                                 return -1;
34133                         }
34134                 }
34135 -               
34136 +
34137                 if (groupname) {
34138                         if (NULL == (grp = getgrnam(groupname))) {
34139 -                               fprintf(stderr, "%s.%d: %s %s\n", 
34140 +                               fprintf(stderr, "%s.%d: %s %s\n",
34141                                         __FILE__, __LINE__,
34142 -                                       "can't find groupname", 
34143 +                                       "can't find groupname",
34144                                         groupname);
34145                                 return -1;
34146                         }
34147                         if (grp->gr_gid == 0) {
34148 -                               fprintf(stderr, "%s.%d: %s\n", 
34149 +                               fprintf(stderr, "%s.%d: %s\n",
34150                                         __FILE__, __LINE__,
34151                                         "I will not set gid to 0\n");
34152                                 return -1;
34153                         }
34154                 }
34155 -               
34156 +
34157                 if (changeroot) {
34158                         if (-1 == chroot(changeroot)) {
34159 -                               fprintf(stderr, "%s.%d: %s %s\n", 
34160 +                               fprintf(stderr, "%s.%d: %s %s\n",
34161                                         __FILE__, __LINE__,
34162                                         "chroot failed: ", strerror(errno));
34163                                 return -1;
34164                         }
34165                         if (-1 == chdir("/")) {
34166 -                               fprintf(stderr, "%s.%d: %s %s\n", 
34167 +                               fprintf(stderr, "%s.%d: %s %s\n",
34168                                         __FILE__, __LINE__,
34169                                         "chdir failed: ", strerror(errno));
34170                                 return -1;
34171                         }
34172                 }
34173 -               
34174 +
34175                 /* drop root privs */
34176                 if (groupname) {
34177                         setgid(grp->gr_gid);
34178 @@ -428,7 +429,7 @@
34179                 }
34180                 if (username) setuid(pwd->pw_uid);
34181         }
34182 -       
34183 +
34184         return fcgi_spawn_connection(fcgi_app, addr, port, unixsocket, child_count, pid_fd, nofork);
34185  }
34186  #else
34187
34188 Property changes on: src/spawn-fcgi.c
34189 ___________________________________________________________________
34190 Name: svn:eol-style
34191    + native
34192
34193 Index: src/mod_sql_vhost_core.h
34194 ===================================================================
34195 --- src/mod_sql_vhost_core.h    (.../tags/lighttpd-1.4.11)      (revision 0)
34196 +++ src/mod_sql_vhost_core.h    (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
34197 @@ -0,0 +1,49 @@
34198 +#ifndef _MOD_SQL_VHOST_CORE_H_
34199 +#define _MOD_SQL_VHOST_CORE_H_
34200 +
34201 +#include "buffer.h"
34202 +#include "plugin.h"
34203 +
34204 +#define SQLVHOST_BACKEND_GETVHOST_PARAMS \
34205 +       (server *srv, connection *con, void *p_d, buffer *docroot, buffer *host)
34206 +
34207 +#define SQLVHOST_BACKEND_GETVHOST_RETVAL handler_t
34208 +
34209 +#define SQLVHOST_BACKEND_GETVHOST(name) \
34210 +       SQLVHOST_BACKEND_GETVHOST_RETVAL name SQLVHOST_BACKEND_GETVHOST_PARAMS
34211 +
34212 +#define SQLVHOST_BACKEND_GETVHOST_PTR(name) \
34213 +       SQLVHOST_BACKEND_GETVHOST_RETVAL (* name)SQLVHOST_BACKEND_GETVHOST_PARAMS
34214 +
34215 +typedef struct {
34216 +       buffer  *db;
34217 +       buffer  *user;
34218 +       buffer  *pass;
34219 +       buffer  *sock;
34220 +
34221 +       buffer  *hostname;
34222 +       unsigned short port;
34223 +
34224 +       buffer  *backend;
34225 +       void *backend_data;
34226 +
34227 +       buffer *select_vhost;
34228 +
34229 +       SQLVHOST_BACKEND_GETVHOST_PTR(get_vhost);
34230 +} mod_sql_vhost_core_plugin_config;
34231 +
34232 +/* global plugin data */
34233 +typedef struct {
34234 +       PLUGIN_DATA;
34235 +
34236 +       buffer  *docroot;
34237 +       buffer  *host;
34238 +
34239 +       mod_sql_vhost_core_plugin_config **config_storage;
34240 +
34241 +       mod_sql_vhost_core_plugin_config conf;
34242 +} mod_sql_vhost_core_plugin_data;
34243 +
34244 +
34245 +
34246 +#endif
34247 Index: src/mod_auth.c
34248 ===================================================================
34249 --- src/mod_auth.c      (.../tags/lighttpd-1.4.11)      (revision 1159)
34250 +++ src/mod_auth.c      (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
34251 @@ -5,168 +5,167 @@
34252  #include <string.h>
34253  #include <errno.h>
34254  #include <fcntl.h>
34255 -#include <unistd.h>
34256  
34257  #include "plugin.h"
34258  #include "http_auth.h"
34259  #include "log.h"
34260  #include "response.h"
34261  
34262 +#include "sys-strings.h"
34263 +#include "sys-files.h"
34264 +
34265  handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s);
34266  
34267  
34268  /**
34269   * the basic and digest auth framework
34270 - * 
34271 + *
34272   * - config handling
34273   * - protocol handling
34274 - * 
34275 - * http_auth.c 
34276 - * http_auth_digest.c 
34277 - * 
34278 + *
34279 + * http_auth.c
34280 + * http_auth_digest.c
34281 + *
34282   * do the real work
34283   */
34284  
34285  INIT_FUNC(mod_auth_init) {
34286         mod_auth_plugin_data *p;
34287 -       
34288 +
34289         p = calloc(1, sizeof(*p));
34290 -       
34291 +
34292         p->tmp_buf = buffer_init();
34293 -       
34294 +
34295         p->auth_user = buffer_init();
34296  #ifdef USE_LDAP
34297         p->ldap_filter = buffer_init();
34298  #endif
34299 -       
34300 +
34301         return p;
34302  }
34303  
34304  FREE_FUNC(mod_auth_free) {
34305         mod_auth_plugin_data *p = p_d;
34306 -       
34307 +
34308         UNUSED(srv);
34309  
34310         if (!p) return HANDLER_GO_ON;
34311 -       
34312 +
34313         buffer_free(p->tmp_buf);
34314         buffer_free(p->auth_user);
34315  #ifdef USE_LDAP
34316         buffer_free(p->ldap_filter);
34317  #endif
34318 -       
34319 +
34320         if (p->config_storage) {
34321                 size_t i;
34322                 for (i = 0; i < srv->config_context->used; i++) {
34323                         mod_auth_plugin_config *s = p->config_storage[i];
34324 -                       
34325 +
34326                         if (!s) continue;
34327 -                       
34328 +
34329                         array_free(s->auth_require);
34330                         buffer_free(s->auth_plain_groupfile);
34331                         buffer_free(s->auth_plain_userfile);
34332                         buffer_free(s->auth_htdigest_userfile);
34333                         buffer_free(s->auth_htpasswd_userfile);
34334                         buffer_free(s->auth_backend_conf);
34335 -                       
34336 +
34337                         buffer_free(s->auth_ldap_hostname);
34338                         buffer_free(s->auth_ldap_basedn);
34339                         buffer_free(s->auth_ldap_binddn);
34340                         buffer_free(s->auth_ldap_bindpw);
34341                         buffer_free(s->auth_ldap_filter);
34342                         buffer_free(s->auth_ldap_cafile);
34343 -                       
34344 +
34345  #ifdef USE_LDAP
34346                         buffer_free(s->ldap_filter_pre);
34347                         buffer_free(s->ldap_filter_post);
34348 -                       
34349 +
34350                         if (s->ldap) ldap_unbind_s(s->ldap);
34351  #endif
34352 -                       
34353 +
34354                         free(s);
34355                 }
34356                 free(p->config_storage);
34357         }
34358 -       
34359 +
34360         free(p);
34361 -       
34362 +
34363         return HANDLER_GO_ON;
34364  }
34365  
34366 -#define PATCH(x) \
34367 -       p->conf.x = s->x;
34368  static int mod_auth_patch_connection(server *srv, connection *con, mod_auth_plugin_data *p) {
34369         size_t i, j;
34370         mod_auth_plugin_config *s = p->config_storage[0];
34371  
34372 -       PATCH(auth_backend);
34373 -       PATCH(auth_plain_groupfile);
34374 -       PATCH(auth_plain_userfile);
34375 -       PATCH(auth_htdigest_userfile);
34376 -       PATCH(auth_htpasswd_userfile);
34377 -       PATCH(auth_require);
34378 -       PATCH(auth_debug);
34379 -       PATCH(auth_ldap_hostname);
34380 -       PATCH(auth_ldap_basedn);
34381 -       PATCH(auth_ldap_binddn);
34382 -       PATCH(auth_ldap_bindpw);
34383 -       PATCH(auth_ldap_filter);
34384 -       PATCH(auth_ldap_cafile);
34385 -       PATCH(auth_ldap_starttls);
34386 +       PATCH_OPTION(auth_backend);
34387 +       PATCH_OPTION(auth_plain_groupfile);
34388 +       PATCH_OPTION(auth_plain_userfile);
34389 +       PATCH_OPTION(auth_htdigest_userfile);
34390 +       PATCH_OPTION(auth_htpasswd_userfile);
34391 +       PATCH_OPTION(auth_require);
34392 +       PATCH_OPTION(auth_debug);
34393 +       PATCH_OPTION(auth_ldap_hostname);
34394 +       PATCH_OPTION(auth_ldap_basedn);
34395 +       PATCH_OPTION(auth_ldap_binddn);
34396 +       PATCH_OPTION(auth_ldap_bindpw);
34397 +       PATCH_OPTION(auth_ldap_filter);
34398 +       PATCH_OPTION(auth_ldap_cafile);
34399 +       PATCH_OPTION(auth_ldap_starttls);
34400  #ifdef USE_LDAP
34401 -       PATCH(ldap);
34402 -       PATCH(ldap_filter_pre);
34403 -       PATCH(ldap_filter_post);
34404 +       PATCH_OPTION(ldap);
34405 +       PATCH_OPTION(ldap_filter_pre);
34406 +       PATCH_OPTION(ldap_filter_post);
34407  #endif
34408 -       
34409 +
34410         /* skip the first, the global context */
34411         for (i = 1; i < srv->config_context->used; i++) {
34412                 data_config *dc = (data_config *)srv->config_context->data[i];
34413                 s = p->config_storage[i];
34414 -               
34415 +
34416                 /* condition didn't match */
34417                 if (!config_check_cond(srv, con, dc)) continue;
34418 -               
34419 +
34420                 /* merge config */
34421                 for (j = 0; j < dc->value->used; j++) {
34422                         data_unset *du = dc->value->data[j];
34423 -                       
34424 +
34425                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend"))) {
34426 -                               PATCH(auth_backend);
34427 +                               PATCH_OPTION(auth_backend);
34428                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.plain.groupfile"))) {
34429 -                               PATCH(auth_plain_groupfile);
34430 +                               PATCH_OPTION(auth_plain_groupfile);
34431                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.plain.userfile"))) {
34432 -                               PATCH(auth_plain_userfile);
34433 +                               PATCH_OPTION(auth_plain_userfile);
34434                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.htdigest.userfile"))) {
34435 -                               PATCH(auth_htdigest_userfile);
34436 +                               PATCH_OPTION(auth_htdigest_userfile);
34437                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.htpasswd.userfile"))) {
34438 -                               PATCH(auth_htpasswd_userfile);
34439 +                               PATCH_OPTION(auth_htpasswd_userfile);
34440                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.require"))) {
34441 -                               PATCH(auth_require);
34442 +                               PATCH_OPTION(auth_require);
34443                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.debug"))) {
34444 -                               PATCH(auth_debug);
34445 +                               PATCH_OPTION(auth_debug);
34446                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.hostname"))) {
34447 -                               PATCH(auth_ldap_hostname);
34448 +                               PATCH_OPTION(auth_ldap_hostname);
34449  #ifdef USE_LDAP
34450 -                               PATCH(ldap);
34451 -                               PATCH(ldap_filter_pre);
34452 -                               PATCH(ldap_filter_post);
34453 +                               PATCH_OPTION(ldap);
34454 +                               PATCH_OPTION(ldap_filter_pre);
34455 +                               PATCH_OPTION(ldap_filter_post);
34456  #endif
34457                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.base-dn"))) {
34458 -                               PATCH(auth_ldap_basedn);
34459 +                               PATCH_OPTION(auth_ldap_basedn);
34460                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.filter"))) {
34461 -                               PATCH(auth_ldap_filter);
34462 +                               PATCH_OPTION(auth_ldap_filter);
34463                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.ca-file"))) {
34464 -                               PATCH(auth_ldap_cafile);
34465 +                               PATCH_OPTION(auth_ldap_cafile);
34466                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.starttls"))) {
34467 -                               PATCH(auth_ldap_starttls);
34468 +                               PATCH_OPTION(auth_ldap_starttls);
34469                         }
34470                 }
34471         }
34472 -       
34473 +
34474         return 0;
34475  }
34476 -#undef PATCH
34477  
34478  static handler_t mod_auth_uri_handler(server *srv, connection *con, void *p_d) {
34479         size_t k;
34480 @@ -175,22 +174,22 @@
34481         data_string *ds;
34482         mod_auth_plugin_data *p = p_d;
34483         array *req;
34484 -       
34485 +
34486         /* select the right config */
34487         mod_auth_patch_connection(srv, con, p);
34488 -       
34489 +
34490         if (p->conf.auth_require == NULL) return HANDLER_GO_ON;
34491 -       
34492 +
34493         /*
34494          * AUTH
34495 -        *  
34496 +        *
34497          */
34498 -       
34499 +
34500         /* do we have to ask for auth ? */
34501 -       
34502 +
34503         auth_required = 0;
34504         auth_satisfied = 0;
34505 -       
34506 +
34507         /* search auth-directives for path */
34508         for (k = 0; k < p->conf.auth_require->used; k++) {
34509                 buffer *req = p->conf.auth_require->data[k]->key;
34510 @@ -212,31 +211,31 @@
34511                         }
34512                 }
34513         }
34514 -       
34515 +
34516         /* nothing to do for us */
34517         if (auth_required == 0) return HANDLER_GO_ON;
34518 -       
34519 +
34520         req = ((data_array *)(p->conf.auth_require->data[k]))->value;
34521 -       
34522 +
34523         /* try to get Authorization-header */
34524 -               
34525 +
34526         if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Authorization"))) {
34527                 http_authorization = ds->value->ptr;
34528         }
34529 -       
34530 +
34531         if (ds && ds->value && ds->value->used) {
34532                 char *auth_realm;
34533                 data_string *method;
34534 -               
34535 +
34536                 method = (data_string *)array_get_element(req, "method");
34537 -               
34538 +
34539                 /* parse auth-header */
34540                 if (NULL != (auth_realm = strchr(http_authorization, ' '))) {
34541                         int auth_type_len = auth_realm - http_authorization;
34542 -                       
34543 +
34544                         if ((auth_type_len == 5) &&
34545                             (0 == strncmp(http_authorization, "Basic", auth_type_len))) {
34546 -                               
34547 +
34548                                 if (0 == strcmp(method->value->ptr, "basic")) {
34549                                         auth_satisfied = http_auth_basic_check(srv, con, p, req, con->uri.path, auth_realm+1);
34550                                 }
34551 @@ -245,43 +244,43 @@
34552                                 if (0 == strcmp(method->value->ptr, "digest")) {
34553                                         if (-1 == (auth_satisfied = http_auth_digest_check(srv, con, p, req, con->uri.path, auth_realm+1))) {
34554                                                 con->http_status = 400;
34555 -                                               
34556 +
34557                                                 /* a field was missing */
34558 -                                               
34559 +
34560                                                 return HANDLER_FINISHED;
34561                                         }
34562                                 }
34563                         } else {
34564 -                               log_error_write(srv, __FILE__, __LINE__, "ss", 
34565 +                               log_error_write(srv, __FILE__, __LINE__, "ss",
34566                                                 "unknown authentification type:",
34567                                                 http_authorization);
34568                         }
34569                 }
34570         }
34571 -       
34572 +
34573         if (!auth_satisfied) {
34574                 data_string *method, *realm;
34575                 method = (data_string *)array_get_element(req, "method");
34576                 realm = (data_string *)array_get_element(req, "realm");
34577 -               
34578 +
34579                 con->http_status = 401;
34580 -                       
34581 +
34582                 if (0 == strcmp(method->value->ptr, "basic")) {
34583                         buffer_copy_string(p->tmp_buf, "Basic realm=\"");
34584                         buffer_append_string_buffer(p->tmp_buf, realm->value);
34585                         buffer_append_string(p->tmp_buf, "\"");
34586 -                       
34587 +
34588                         response_header_insert(srv, con, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(p->tmp_buf));
34589                 } else if (0 == strcmp(method->value->ptr, "digest")) {
34590                         char hh[33];
34591                         http_auth_digest_generate_nonce(srv, p, srv->tmp_buf, hh);
34592 -                       
34593 +
34594                         buffer_copy_string(p->tmp_buf, "Digest realm=\"");
34595                         buffer_append_string_buffer(p->tmp_buf, realm->value);
34596                         buffer_append_string(p->tmp_buf, "\", nonce=\"");
34597                         buffer_append_string(p->tmp_buf, hh);
34598                         buffer_append_string(p->tmp_buf, "\", qop=\"auth\"");
34599 -                       
34600 +
34601                         response_header_insert(srv, con, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(p->tmp_buf));
34602                 } else {
34603                         /* evil */
34604 @@ -289,18 +288,18 @@
34605                 return HANDLER_FINISHED;
34606         } else {
34607                 /* the REMOTE_USER header */
34608 -               
34609 +
34610                 buffer_copy_string_buffer(con->authed_user, p->auth_user);
34611         }
34612 -       
34613 +
34614         return HANDLER_GO_ON;
34615  }
34616  
34617  SETDEFAULTS_FUNC(mod_auth_set_defaults) {
34618         mod_auth_plugin_data *p = p_d;
34619         size_t i;
34620 -       
34621 -       config_values_t cv[] = { 
34622 +
34623 +       config_values_t cv[] = {
34624                 { "auth.backend",                   NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
34625                 { "auth.backend.plain.groupfile",   NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
34626                 { "auth.backend.plain.userfile",    NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
34627 @@ -317,7 +316,7 @@
34628                 { "auth.debug",                     NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },  /* 13 */
34629                 { NULL,                             NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
34630         };
34631 -       
34632 +
34633         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
34634  
34635         for (i = 0; i < srv->config_context->used; i++) {
34636 @@ -325,14 +324,14 @@
34637                 size_t n;
34638                 data_array *da;
34639                 array *ca;
34640 -               
34641 +
34642                 s = calloc(1, sizeof(mod_auth_plugin_config));
34643                 s->auth_plain_groupfile = buffer_init();
34644                 s->auth_plain_userfile = buffer_init();
34645                 s->auth_htdigest_userfile = buffer_init();
34646                 s->auth_htpasswd_userfile = buffer_init();
34647                 s->auth_backend_conf = buffer_init();
34648 -               
34649 +
34650                 s->auth_ldap_hostname = buffer_init();
34651                 s->auth_ldap_basedn = buffer_init();
34652                 s->auth_ldap_binddn = buffer_init();
34653 @@ -341,15 +340,15 @@
34654                 s->auth_ldap_cafile = buffer_init();
34655                 s->auth_ldap_starttls = 0;
34656                 s->auth_debug = 0;
34657 -               
34658 +
34659                 s->auth_require = array_init();
34660 -               
34661 +
34662  #ifdef USE_LDAP
34663                 s->ldap_filter_pre = buffer_init();
34664                 s->ldap_filter_post = buffer_init();
34665                 s->ldap = NULL;
34666  #endif
34667 -       
34668 +
34669                 cv[0].destination = s->auth_backend_conf;
34670                 cv[1].destination = s->auth_plain_groupfile;
34671                 cv[2].destination = s->auth_plain_userfile;
34672 @@ -364,14 +363,14 @@
34673                 cv[11].destination = s->auth_htdigest_userfile;
34674                 cv[12].destination = s->auth_htpasswd_userfile;
34675                 cv[13].destination = &(s->auth_debug);
34676 -               
34677 +
34678                 p->config_storage[i] = s;
34679                 ca = ((data_config *)srv->config_context->data[i])->value;
34680 -               
34681 +
34682                 if (0 != config_insert_values_global(srv, ca, cv)) {
34683                         return HANDLER_ERROR;
34684                 }
34685 -               
34686 +
34687                 if (s->auth_backend_conf->used) {
34688                         if (0 == strcmp(s->auth_backend_conf->ptr, "htpasswd")) {
34689                                 s->auth_backend = AUTH_BACKEND_HTPASSWD;
34690 @@ -383,31 +382,31 @@
34691                                 s->auth_backend = AUTH_BACKEND_LDAP;
34692                         } else {
34693                                 log_error_write(srv, __FILE__, __LINE__, "sb", "auth.backend not supported:", s->auth_backend_conf);
34694 -                               
34695 +
34696                                 return HANDLER_ERROR;
34697                         }
34698                 }
34699  
34700                 /* no auth.require for this section */
34701                 if (NULL == (da = (data_array *)array_get_element(ca, "auth.require"))) continue;
34702 -               
34703 +
34704                 if (da->type != TYPE_ARRAY) continue;
34705 -               
34706 +
34707                 for (n = 0; n < da->value->used; n++) {
34708                         size_t m;
34709                         data_array *da_file = (data_array *)da->value->data[n];
34710                         const char *method, *realm, *require;
34711 -                       
34712 +
34713                         if (da->value->data[n]->type != TYPE_ARRAY) {
34714 -                               log_error_write(srv, __FILE__, __LINE__, "ss", 
34715 -                                               "auth.require should contain an array as in:", 
34716 +                               log_error_write(srv, __FILE__, __LINE__, "ss",
34717 +                                               "auth.require should contain an array as in:",
34718                                                 "auth.require = ( \"...\" => ( ..., ...) )");
34719  
34720                                 return HANDLER_ERROR;
34721                         }
34722 -                                       
34723 +
34724                         method = realm = require = NULL;
34725 -                                       
34726 +
34727                         for (m = 0; m < da_file->value->used; m++) {
34728                                 if (da_file->value->data[m]->type == TYPE_STRING) {
34729                                         if (0 == strcmp(da_file->value->data[m]->key->ptr, "method")) {
34730 @@ -417,8 +416,8 @@
34731                                         } else if (0 == strcmp(da_file->value->data[m]->key->ptr, "require")) {
34732                                                 require = ((data_string *)(da_file->value->data[m]))->value->ptr;
34733                                         } else {
34734 -                                               log_error_write(srv, __FILE__, __LINE__, "ssbs", 
34735 -                                                       "the field is unknown in:", 
34736 +                                               log_error_write(srv, __FILE__, __LINE__, "ssbs",
34737 +                                                       "the field is unknown in:",
34738                                                         "auth.require = ( \"...\" => ( ..., -> \"",
34739                                                         da_file->value->data[m]->key,
34740                                                         "\" <- => \"...\" ) )");
34741 @@ -426,19 +425,19 @@
34742                                                 return HANDLER_ERROR;
34743                                         }
34744                                 } else {
34745 -                                       log_error_write(srv, __FILE__, __LINE__, "ssbs", 
34746 -                                               "a string was expected for:", 
34747 +                                       log_error_write(srv, __FILE__, __LINE__, "ssbs",
34748 +                                               "a string was expected for:",
34749                                                 "auth.require = ( \"...\" => ( ..., -> \"",
34750                                                 da_file->value->data[m]->key,
34751                                                 "\" <- => \"...\" ) )");
34752 -                                       
34753 +
34754                                         return HANDLER_ERROR;
34755                                 }
34756                         }
34757 -                                       
34758 +
34759                         if (method == NULL) {
34760 -                               log_error_write(srv, __FILE__, __LINE__, "ss", 
34761 -                                               "the require field is missing in:", 
34762 +                               log_error_write(srv, __FILE__, __LINE__, "ss",
34763 +                                               "the require field is missing in:",
34764                                                 "auth.require = ( \"...\" => ( ..., \"method\" => \"...\" ) )");
34765                                 return HANDLER_ERROR;
34766                         } else {
34767 @@ -450,60 +449,60 @@
34768                                         return HANDLER_ERROR;
34769                                 }
34770                         }
34771 -                       
34772 +
34773                         if (realm == NULL) {
34774 -                               log_error_write(srv, __FILE__, __LINE__, "ss", 
34775 -                                               "the require field is missing in:", 
34776 +                               log_error_write(srv, __FILE__, __LINE__, "ss",
34777 +                                               "the require field is missing in:",
34778                                                 "auth.require = ( \"...\" => ( ..., \"realm\" => \"...\" ) )");
34779                                 return HANDLER_ERROR;
34780                         }
34781 -                       
34782 +
34783                         if (require == NULL) {
34784 -                               log_error_write(srv, __FILE__, __LINE__, "ss", 
34785 -                                               "the require field is missing in:", 
34786 +                               log_error_write(srv, __FILE__, __LINE__, "ss",
34787 +                                               "the require field is missing in:",
34788                                                 "auth.require = ( \"...\" => ( ..., \"require\" => \"...\" ) )");
34789                                 return HANDLER_ERROR;
34790                         }
34791 -                       
34792 +
34793                         if (method && realm && require) {
34794                                 data_string *ds;
34795                                 data_array *a;
34796 -                               
34797 +
34798                                 a = data_array_init();
34799                                 buffer_copy_string_buffer(a->key, da_file->key);
34800 -                               
34801 +
34802                                 ds = data_string_init();
34803 -                               
34804 +
34805                                 buffer_copy_string(ds->key, "method");
34806                                 buffer_copy_string(ds->value, method);
34807 -                               
34808 +
34809                                 array_insert_unique(a->value, (data_unset *)ds);
34810 -                               
34811 +
34812                                 ds = data_string_init();
34813 -                               
34814 +
34815                                 buffer_copy_string(ds->key, "realm");
34816                                 buffer_copy_string(ds->value, realm);
34817 -                               
34818 +
34819                                 array_insert_unique(a->value, (data_unset *)ds);
34820 -                               
34821 +
34822                                 ds = data_string_init();
34823 -                               
34824 +
34825                                 buffer_copy_string(ds->key, "require");
34826                                 buffer_copy_string(ds->value, require);
34827 -                               
34828 +
34829                                 array_insert_unique(a->value, (data_unset *)ds);
34830 -                               
34831 +
34832                                 array_insert_unique(s->auth_require, (data_unset *)a);
34833                         }
34834                 }
34835 -       
34836 +
34837                 switch(s->auth_backend) {
34838                 case AUTH_BACKEND_PLAIN:
34839                         if (s->auth_plain_userfile->used) {
34840                                 int fd;
34841                                 /* try to read */
34842                                 if (-1 == (fd = open(s->auth_plain_userfile->ptr, O_RDONLY))) {
34843 -                                       log_error_write(srv, __FILE__, __LINE__, "sbss", 
34844 +                                       log_error_write(srv, __FILE__, __LINE__, "sbss",
34845                                                         "opening auth.backend.plain.userfile:", s->auth_plain_userfile,
34846                                                         "failed:", strerror(errno));
34847                                         return HANDLER_ERROR;
34848 @@ -516,7 +515,7 @@
34849                                 int fd;
34850                                 /* try to read */
34851                                 if (-1 == (fd = open(s->auth_htpasswd_userfile->ptr, O_RDONLY))) {
34852 -                                       log_error_write(srv, __FILE__, __LINE__, "sbss", 
34853 +                                       log_error_write(srv, __FILE__, __LINE__, "sbss",
34854                                                         "opening auth.backend.htpasswd.userfile:", s->auth_htpasswd_userfile,
34855                                                         "failed:", strerror(errno));
34856                                         return HANDLER_ERROR;
34857 @@ -529,7 +528,7 @@
34858                                 int fd;
34859                                 /* try to read */
34860                                 if (-1 == (fd = open(s->auth_htdigest_userfile->ptr, O_RDONLY))) {
34861 -                                       log_error_write(srv, __FILE__, __LINE__, "sbss", 
34862 +                                       log_error_write(srv, __FILE__, __LINE__, "sbss",
34863                                                         "opening auth.backend.htdigest.userfile:", s->auth_htdigest_userfile,
34864                                                         "failed:", strerror(errno));
34865                                         return HANDLER_ERROR;
34866 @@ -554,75 +553,75 @@
34867  handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s) {
34868  #ifdef USE_LDAP
34869                         int ret;
34870 -#if 0                  
34871 +#if 0
34872                         if (s->auth_ldap_basedn->used == 0) {
34873                                 log_error_write(srv, __FILE__, __LINE__, "s", "ldap: auth.backend.ldap.base-dn has to be set");
34874 -                               
34875 +
34876                                 return HANDLER_ERROR;
34877                         }
34878  #endif
34879 -                       
34880 +
34881                         if (s->auth_ldap_filter->used) {
34882                                 char *dollar;
34883 -                               
34884 +
34885                                 /* parse filter */
34886 -                       
34887 +
34888                                 if (NULL == (dollar = strchr(s->auth_ldap_filter->ptr, '$'))) {
34889                                         log_error_write(srv, __FILE__, __LINE__, "s", "ldap: auth.backend.ldap.filter is missing a replace-operator '$'");
34890 -                                       
34891 +
34892                                         return HANDLER_ERROR;
34893                                 }
34894 -                               
34895 +
34896                                 buffer_copy_string_len(s->ldap_filter_pre, s->auth_ldap_filter->ptr, dollar - s->auth_ldap_filter->ptr);
34897                                 buffer_copy_string(s->ldap_filter_post, dollar+1);
34898                         }
34899 -                       
34900 +
34901                         if (s->auth_ldap_hostname->used) {
34902                                 if (NULL == (s->ldap = ldap_init(s->auth_ldap_hostname->ptr, LDAP_PORT))) {
34903                                         log_error_write(srv, __FILE__, __LINE__, "ss", "ldap ...", strerror(errno));
34904 -                                       
34905 +
34906                                         return HANDLER_ERROR;
34907                                 }
34908 -                               
34909 +
34910                                 ret = LDAP_VERSION3;
34911                                 if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(s->ldap, LDAP_OPT_PROTOCOL_VERSION, &ret))) {
34912                                         log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
34913 -                               
34914 +
34915                                         return HANDLER_ERROR;
34916                                 }
34917  
34918                                 if (s->auth_ldap_starttls) {
34919 -                                       /* if no CA file is given, it is ok, as we will use encryption 
34920 +                                       /* if no CA file is given, it is ok, as we will use encryption
34921                                          * if the server requires a CAfile it will tell us */
34922                                         if (!buffer_is_empty(s->auth_ldap_cafile)) {
34923 -                                               if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, 
34924 +                                               if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
34925                                                                                 s->auth_ldap_cafile->ptr))) {
34926 -                                                       log_error_write(srv, __FILE__, __LINE__, "ss", 
34927 +                                                       log_error_write(srv, __FILE__, __LINE__, "ss",
34928                                                                         "Loading CA certificate failed:", ldap_err2string(ret));
34929 -                                               
34930 +
34931                                                         return HANDLER_ERROR;
34932                                                 }
34933                                         }
34934 -       
34935 +
34936                                         if (LDAP_OPT_SUCCESS != (ret = ldap_start_tls_s(s->ldap, NULL,  NULL))) {
34937                                                 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap startTLS failed:", ldap_err2string(ret));
34938 -                                               
34939 +
34940                                                 return HANDLER_ERROR;
34941                                         }
34942                                 }
34943 -                               
34944 -                               
34945 +
34946 +
34947                                 /* 1. */
34948                                 if (s->auth_ldap_binddn->used) {
34949                                         if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, s->auth_ldap_binddn->ptr, s->auth_ldap_bindpw->ptr))) {
34950                                                 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
34951 -                                               
34952 +
34953                                                 return HANDLER_ERROR;
34954                                         }
34955                                 } else {
34956                                         if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, NULL, NULL))) {
34957                                                 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));
34958 -                                               
34959 +
34960                                                 return HANDLER_ERROR;
34961                                         }
34962                                 }
34963 @@ -641,8 +640,8 @@
34964         p->set_defaults = mod_auth_set_defaults;
34965         p->handle_uri_clean = mod_auth_uri_handler;
34966         p->cleanup     = mod_auth_free;
34967 -       
34968 +
34969         p->data        = NULL;
34970 -       
34971 +
34972         return 0;
34973  }
34974
34975 Property changes on: src/mod_auth.c
34976 ___________________________________________________________________
34977 Name: svn:eol-style
34978    + native
34979
34980 Index: src/mod_ssi.h
34981 ===================================================================
34982 --- src/mod_ssi.h       (.../tags/lighttpd-1.4.11)      (revision 1159)
34983 +++ src/mod_ssi.h       (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
34984 @@ -19,23 +19,23 @@
34985  
34986  typedef struct {
34987         PLUGIN_DATA;
34988 -       
34989 -#ifdef HAVE_PCRE_H     
34990 +
34991 +#ifdef HAVE_PCRE_H
34992         pcre *ssi_regex;
34993 -#endif 
34994 +#endif
34995         buffer *timefmt;
34996         int sizefmt;
34997 -       
34998 +
34999         buffer *stat_fn;
35000 -       
35001 +
35002         array *ssi_vars;
35003         array *ssi_cgi_env;
35004 -       
35005 +
35006         int if_level, if_is_false_level, if_is_false, if_is_false_endif;
35007 -       
35008 +
35009         plugin_config **config_storage;
35010 -       
35011 -       plugin_config conf; 
35012 +
35013 +       plugin_config conf;
35014  } plugin_data;
35015  
35016  int ssi_eval_expr(server *srv, connection *con, plugin_data *p, const char *expr);
35017
35018 Property changes on: src/mod_ssi.h
35019 ___________________________________________________________________
35020 Name: svn:eol-style
35021    + native
35022
35023 Index: src/settings.h
35024 ===================================================================
35025 --- src/settings.h      (.../tags/lighttpd-1.4.11)      (revision 1159)
35026 +++ src/settings.h      (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
35027 @@ -9,24 +9,24 @@
35028  /**
35029   * max size of a buffer which will just be reset
35030   * to ->used = 0 instead of really freeing the buffer
35031 - * 
35032 + *
35033   * 64kB (no real reason, just a guess)
35034   */
35035  #define BUFFER_MAX_REUSE_SIZE  (4 * 1024)
35036  
35037  /**
35038   * max size of the HTTP request header
35039 - * 
35040 + *
35041   * 32k should be enough for everything (just a guess)
35042 - * 
35043 + *
35044   */
35045  #define MAX_HTTP_REQUEST_HEADER  (32 * 1024)
35046  
35047 -typedef enum { HANDLER_UNSET, 
35048 -               HANDLER_GO_ON, 
35049 +typedef enum { HANDLER_UNSET,
35050 +               HANDLER_GO_ON,
35051                 HANDLER_FINISHED,
35052 -               HANDLER_COMEBACK, 
35053 -               HANDLER_WAIT_FOR_EVENT, 
35054 +               HANDLER_COMEBACK,
35055 +               HANDLER_WAIT_FOR_EVENT,
35056                 HANDLER_ERROR,
35057                 HANDLER_WAIT_FOR_FD
35058  } handler_t;
35059
35060 Property changes on: src/settings.h
35061 ___________________________________________________________________
35062 Name: svn:eol-style
35063    + native
35064
35065
35066 Property changes on: src/mod_auth.h
35067 ___________________________________________________________________
35068 Name: svn:eol-style
35069    + native
35070
35071 Index: src/mod_cml_lua.c
35072 ===================================================================
35073 --- src/mod_cml_lua.c   (.../tags/lighttpd-1.4.11)      (revision 1159)
35074 +++ src/mod_cml_lua.c   (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
35075 @@ -23,7 +23,7 @@
35076  #ifdef USE_OPENSSL
35077  #define IN const
35078  #else
35079 -#define IN 
35080 +#define IN
35081  #endif
35082  #define OUT
35083  
35084 @@ -31,6 +31,7 @@
35085  
35086  #include <lua.h>
35087  #include <lualib.h>
35088 +#include <lauxlib.h>
35089  
35090  typedef struct {
35091         stream st;
35092 @@ -39,11 +40,11 @@
35093  
35094  static const char * load_file(lua_State *L, void *data, size_t *size) {
35095         readme *rm = data;
35096 -       
35097 +
35098         UNUSED(L);
35099 -       
35100 +
35101         if (rm->done) return 0;
35102 -       
35103 +
35104         *size = rm->st.size;
35105         rm->done = 1;
35106         return rm->st.start;
35107 @@ -51,47 +52,47 @@
35108  
35109  static int lua_to_c_get_string(lua_State *L, const char *varname, buffer *b) {
35110         int curelem;
35111 -       
35112 +
35113         lua_pushstring(L, varname);
35114 -       
35115 +
35116         curelem = lua_gettop(L);
35117         lua_gettable(L, LUA_GLOBALSINDEX);
35118 -       
35119 +
35120         /* it should be a table */
35121         if (!lua_isstring(L, curelem)) {
35122                 lua_settop(L, curelem - 1);
35123 -               
35124 +
35125                 return -1;
35126         }
35127 -       
35128 +
35129         buffer_copy_string(b, lua_tostring(L, curelem));
35130 -       
35131 +
35132         lua_pop(L, 1);
35133 -       
35134 +
35135         assert(curelem - 1 == lua_gettop(L));
35136 -       
35137 +
35138         return 0;
35139  }
35140  
35141  static int lua_to_c_is_table(lua_State *L, const char *varname) {
35142         int curelem;
35143 -       
35144 +
35145         lua_pushstring(L, varname);
35146 -       
35147 +
35148         curelem = lua_gettop(L);
35149         lua_gettable(L, LUA_GLOBALSINDEX);
35150 -       
35151 +
35152         /* it should be a table */
35153         if (!lua_istable(L, curelem)) {
35154                 lua_settop(L, curelem - 1);
35155 -               
35156 +
35157                 return 0;
35158         }
35159 -       
35160 +
35161         lua_settop(L, curelem - 1);
35162 -       
35163 +
35164         assert(curelem - 1 == lua_gettop(L));
35165 -       
35166 +
35167         return 1;
35168  }
35169  
35170 @@ -99,7 +100,7 @@
35171         lua_pushlstring(L, key, key_len);
35172         lua_pushlstring(L, val, val_len);
35173         lua_settable(L, tbl);
35174 -       
35175 +
35176         return 0;
35177  }
35178  
35179 @@ -108,21 +109,21 @@
35180         size_t is_key = 1;
35181         size_t i;
35182         char *key = NULL, *val = NULL;
35183 -       
35184 +
35185         key = qrystr->ptr;
35186 -       
35187 +
35188         /* we need the \0 */
35189         for (i = 0; i < qrystr->used; i++) {
35190                 switch(qrystr->ptr[i]) {
35191                 case '=':
35192                         if (is_key) {
35193                                 val = qrystr->ptr + i + 1;
35194 -                               
35195 +
35196                                 qrystr->ptr[i] = '\0';
35197 -                               
35198 +
35199                                 is_key = 0;
35200                         }
35201 -                       
35202 +
35203                         break;
35204                 case '&':
35205                 case '\0': /* fin symbol */
35206 @@ -131,19 +132,19 @@
35207  
35208                                 /* terminate the value */
35209                                 qrystr->ptr[i] = '\0';
35210 -                               
35211 -                               c_to_lua_push(L, tbl, 
35212 +
35213 +                               c_to_lua_push(L, tbl,
35214                                               key, strlen(key),
35215                                               val, strlen(val));
35216                         }
35217 -                       
35218 +
35219                         key = qrystr->ptr + i + 1;
35220                         val = NULL;
35221                         is_key = 1;
35222                         break;
35223                 }
35224         }
35225 -       
35226 +
35227         return 0;
35228  }
35229  #if 0
35230 @@ -151,21 +152,21 @@
35231         data_unset *d;
35232  
35233         UNUSED(srv);
35234 -       
35235 +
35236         if (NULL != (d = array_get_element(con->request.headers, "Cookie"))) {
35237                 data_string *ds = (data_string *)d;
35238                 size_t key = 0, value = 0;
35239                 size_t is_key = 1, is_sid = 0;
35240                 size_t i;
35241 -               
35242 +
35243                 /* found COOKIE */
35244                 if (!DATA_IS_STRING(d)) return -1;
35245                 if (ds->value->used == 0) return -1;
35246 -                       
35247 +
35248                 if (ds->value->ptr[0] == '\0' ||
35249                     ds->value->ptr[0] == '=' ||
35250                     ds->value->ptr[0] == ';') return -1;
35251 -               
35252 +
35253                 buffer_reset(p->session_id);
35254                 for (i = 0; i < ds->value->used; i++) {
35255                         switch(ds->value->ptr[i]) {
35256 @@ -176,16 +177,16 @@
35257                                                 is_sid = 1;
35258                                         }
35259                                         value = i + 1;
35260 -                               
35261 +
35262                                         is_key = 0;
35263                                 }
35264 -                               
35265 +
35266                                 break;
35267                         case ';':
35268                                 if (is_sid) {
35269                                         buffer_copy_string_len(p->session_id, ds->value->ptr + value, i - value);
35270                                 }
35271 -                               
35272 +
35273                                 is_sid = 0;
35274                                 key = i + 1;
35275                                 value = 0;
35276 @@ -204,48 +205,43 @@
35277                         }
35278                 }
35279         }
35280 -       
35281 +
35282         return 0;
35283  }
35284  #endif
35285  
35286  int cache_parse_lua(server *srv, connection *con, plugin_data *p, buffer *fn) {
35287 -       lua_State *L; 
35288 +       lua_State *L;
35289         readme rm;
35290         int ret = -1;
35291         buffer *b = buffer_init();
35292         int header_tbl = 0;
35293 -       
35294 +
35295         rm.done = 0;
35296         stream_open(&rm.st, fn);
35297 -       
35298 +
35299         /* push the lua file to the interpreter and see what happends */
35300 -       L = lua_open();
35301 -       
35302 -       luaopen_base(L);
35303 -       luaopen_table(L);
35304 -       luaopen_string(L);
35305 -       luaopen_math(L);
35306 -       luaopen_io(L);
35307 -       
35308 +       L = luaL_newstate();
35309 +       luaL_openlibs(L);
35310 +
35311         /* register functions */
35312         lua_register(L, "md5", f_crypto_md5);
35313         lua_register(L, "file_mtime", f_file_mtime);
35314         lua_register(L, "file_isreg", f_file_isreg);
35315         lua_register(L, "file_isdir", f_file_isreg);
35316         lua_register(L, "dir_files", f_dir_files);
35317 -       
35318 +
35319  #ifdef HAVE_MEMCACHE_H
35320         lua_pushliteral(L, "memcache_get_long");
35321         lua_pushlightuserdata(L, p->conf.mc);
35322         lua_pushcclosure(L, f_memcache_get_long, 1);
35323         lua_settable(L, LUA_GLOBALSINDEX);
35324 -       
35325 +
35326         lua_pushliteral(L, "memcache_get_string");
35327         lua_pushlightuserdata(L, p->conf.mc);
35328         lua_pushcclosure(L, f_memcache_get_string, 1);
35329         lua_settable(L, LUA_GLOBALSINDEX);
35330 -       
35331 +
35332         lua_pushliteral(L, "memcache_exists");
35333         lua_pushlightuserdata(L, p->conf.mc);
35334         lua_pushcclosure(L, f_memcache_exists, 1);
35335 @@ -255,11 +251,11 @@
35336         lua_pushliteral(L, "request");
35337         lua_newtable(L);
35338         lua_settable(L, LUA_GLOBALSINDEX);
35339 -       
35340 +
35341         lua_pushliteral(L, "request");
35342         header_tbl = lua_gettop(L);
35343         lua_gettable(L, LUA_GLOBALSINDEX);
35344 -       
35345 +
35346         c_to_lua_push(L, header_tbl, CONST_STR_LEN("REQUEST_URI"), CONST_BUF_LEN(con->request.orig_uri));
35347         c_to_lua_push(L, header_tbl, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path));
35348         c_to_lua_push(L, header_tbl, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(con->physical.path));
35349 @@ -267,84 +263,84 @@
35350         if (!buffer_is_empty(con->request.pathinfo)) {
35351                 c_to_lua_push(L, header_tbl, CONST_STR_LEN("PATH_INFO"), CONST_BUF_LEN(con->request.pathinfo));
35352         }
35353 -       
35354 +
35355         c_to_lua_push(L, header_tbl, CONST_STR_LEN("CWD"), CONST_BUF_LEN(p->basedir));
35356         c_to_lua_push(L, header_tbl, CONST_STR_LEN("BASEURL"), CONST_BUF_LEN(p->baseurl));
35357 -       
35358 +
35359         /* register GET parameter */
35360         lua_pushliteral(L, "get");
35361         lua_newtable(L);
35362         lua_settable(L, LUA_GLOBALSINDEX);
35363 -       
35364 +
35365         lua_pushliteral(L, "get");
35366         header_tbl = lua_gettop(L);
35367         lua_gettable(L, LUA_GLOBALSINDEX);
35368 -       
35369 +
35370         buffer_copy_string_buffer(b, con->uri.query);
35371         cache_export_get_params(L, header_tbl, b);
35372         buffer_reset(b);
35373  
35374 -       /* 2 default constants */       
35375 +       /* 2 default constants */
35376         lua_pushliteral(L, "CACHE_HIT");
35377         lua_pushboolean(L, 0);
35378         lua_settable(L, LUA_GLOBALSINDEX);
35379 -       
35380 +
35381         lua_pushliteral(L, "CACHE_MISS");
35382         lua_pushboolean(L, 1);
35383         lua_settable(L, LUA_GLOBALSINDEX);
35384 -       
35385 +
35386         /* load lua program */
35387         if (lua_load(L, load_file, &rm, fn->ptr) || lua_pcall(L,0,1,0)) {
35388                 log_error_write(srv, __FILE__, __LINE__, "s",
35389                                 lua_tostring(L,-1));
35390 -               
35391 +
35392                 goto error;
35393         }
35394 -       
35395 +
35396         /* get return value */
35397         ret = (int)lua_tonumber(L, -1);
35398         lua_pop(L, 1);
35399 -       
35400 -       /* fetch the data from lua */ 
35401 +
35402 +       /* fetch the data from lua */
35403         lua_to_c_get_string(L, "trigger_handler", p->trigger_handler);
35404 -       
35405 +
35406         if (0 == lua_to_c_get_string(L, "output_contenttype", b)) {
35407                 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(b));
35408         }
35409 -       
35410 +
35411         if (ret == 0) {
35412                 /* up to now it is a cache-hit, check if all files exist */
35413 -               
35414 +
35415                 int curelem;
35416                 time_t mtime = 0;
35417 -       
35418 +
35419                 if (!lua_to_c_is_table(L, "output_include")) {
35420                         log_error_write(srv, __FILE__, __LINE__, "s",
35421                                 "output_include is missing or not a table");
35422                         ret = -1;
35423 -               
35424 +
35425                         goto error;
35426                 }
35427 -               
35428 +
35429                 lua_pushstring(L, "output_include");
35430 -               
35431 +
35432                 curelem = lua_gettop(L);
35433                 lua_gettable(L, LUA_GLOBALSINDEX);
35434  
35435                 /* HOW-TO build a etag ?
35436 -                * as we don't just have one file we have to take the stat() 
35437 +                * as we don't just have one file we have to take the stat()
35438                  * from all base files, merge them and build the etag from
35439                  * it later.
35440 -                * 
35441 +                *
35442                  * The mtime of the content is the mtime of the freshest base file
35443 -                * 
35444 +                *
35445                  * */
35446 -               
35447 +
35448                 lua_pushnil(L);  /* first key */
35449                 while (lua_next(L, curelem) != 0) {
35450                         stat_cache_entry *sce = NULL;
35451                         /* key' is at index -2 and value' at index -1 */
35452 -                       
35453 +
35454                         if (lua_isstring(L, -1)) {
35455                                 const char *s = lua_tostring(L, -1);
35456  
35457 @@ -364,18 +360,18 @@
35458                                                 /* a file is missing, call the handler to generate it */
35459                                                 if (!buffer_is_empty(p->trigger_handler)) {
35460                                                         ret = 1; /* cache-miss */
35461 -                                                       
35462 +
35463                                                         log_error_write(srv, __FILE__, __LINE__, "s",
35464                                                                         "a file is missing, calling handler");
35465 -                                                       
35466 +
35467                                                         break;
35468                                                 } else {
35469                                                         /* handler not set -> 500 */
35470                                                         ret = -1;
35471 -                                                       
35472 +
35473                                                         log_error_write(srv, __FILE__, __LINE__, "s",
35474                                                                         "a file missing and no handler set");
35475 -                                                       
35476 +
35477                                                         break;
35478                                                 }
35479                                                 break;
35480 @@ -393,12 +389,12 @@
35481                                                 "not a string");
35482                                 break;
35483                         }
35484 -               
35485 +
35486                         lua_pop(L, 1);  /* removes value'; keeps key' for next iteration */
35487                 }
35488 -               
35489 +
35490                 lua_settop(L, curelem - 1);
35491 -               
35492 +
35493                 if (ret == 0) {
35494                         data_string *ds;
35495                         char timebuf[sizeof("Sat, 23 Jul 2005 21:20:01 GMT")];
35496 @@ -410,9 +406,9 @@
35497  
35498                         /* no Last-Modified specified */
35499                         if ((mtime) && (NULL == ds)) {
35500 -               
35501 +
35502                                 strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&mtime));
35503 -                               
35504 +
35505                                 response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), timebuf, sizeof(timebuf) - 1);
35506  
35507  
35508 @@ -428,9 +424,9 @@
35509                                 tbuf.used = 0;
35510                                 tbuf.ptr = NULL;
35511                         }
35512 -                       
35513 +
35514                         if (HANDLER_FINISHED == http_response_handle_cachable(srv, con, &tbuf)) {
35515 -                               /* ok, the client already has our content, 
35516 +                               /* ok, the client already has our content,
35517                                  * no need to send it again */
35518  
35519                                 chunkqueue_reset(con->write_queue);
35520 @@ -440,24 +436,24 @@
35521                         chunkqueue_reset(con->write_queue);
35522                 }
35523         }
35524 -       
35525 +
35526         if (ret == 1 && !buffer_is_empty(p->trigger_handler)) {
35527                 /* cache-miss */
35528                 buffer_copy_string_buffer(con->uri.path, p->baseurl);
35529                 buffer_append_string_buffer(con->uri.path, p->trigger_handler);
35530 -       
35531 +
35532                 buffer_copy_string_buffer(con->physical.path, p->basedir);
35533                 buffer_append_string_buffer(con->physical.path, p->trigger_handler);
35534 -               
35535 +
35536                 chunkqueue_reset(con->write_queue);
35537         }
35538 -       
35539 +
35540  error:
35541         lua_close(L);
35542 -       
35543 +
35544         stream_close(&rm.st);
35545         buffer_free(b);
35546 -       
35547 +
35548         return ret /* cache-error */;
35549  }
35550  #else
35551
35552 Property changes on: src/mod_cml_lua.c
35553 ___________________________________________________________________
35554 Name: svn:eol-style
35555    + native
35556
35557 Index: src/fdevent_linux_rtsig.c
35558 ===================================================================
35559 --- src/fdevent_linux_rtsig.c   (.../tags/lighttpd-1.4.11)      (revision 1159)
35560 +++ src/fdevent_linux_rtsig.c   (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
35561 @@ -1,6 +1,5 @@
35562  #include <sys/types.h>
35563  
35564 -#include <unistd.h>
35565  #include <stdlib.h>
35566  #include <stdio.h>
35567  #include <string.h>
35568 @@ -14,6 +13,7 @@
35569  #include "fdevent.h"
35570  #include "settings.h"
35571  #include "buffer.h"
35572 +#include "sys-process.h"
35573  
35574  #ifdef USE_LINUX_SIGIO
35575  static void fdevent_linux_rtsig_free(fdevents *ev) {
35576 @@ -26,19 +26,19 @@
35577  
35578  static int fdevent_linux_rtsig_event_del(fdevents *ev, int fde_ndx, int fd) {
35579         if (fde_ndx < 0) return -1;
35580 -       
35581 +
35582         if ((size_t)fde_ndx >= ev->used) {
35583                 fprintf(stderr, "%s.%d: del! out of range %d %zu\n", __FILE__, __LINE__, fde_ndx, ev->used);
35584                 SEGFAULT();
35585         }
35586 -       
35587 +
35588         if (ev->pollfds[fde_ndx].fd == fd) {
35589                 size_t k = fde_ndx;
35590 -               
35591 +
35592                 ev->pollfds[k].fd = -1;
35593  
35594                 bitset_clear_bit(ev->sigbset, fd);
35595 -               
35596 +
35597                 if (ev->unused.size == 0) {
35598                         ev->unused.size = 16;
35599                         ev->unused.ptr = malloc(sizeof(*(ev->unused.ptr)) * ev->unused.size);
35600 @@ -46,29 +46,29 @@
35601                         ev->unused.size += 16;
35602                         ev->unused.ptr = realloc(ev->unused.ptr, sizeof(*(ev->unused.ptr)) * ev->unused.size);
35603                 }
35604 -               
35605 +
35606                 ev->unused.ptr[ev->unused.used++] = k;
35607         } else {
35608                 fprintf(stderr, "%s.%d: del! %d %d\n", __FILE__, __LINE__, ev->pollfds[fde_ndx].fd, fd);
35609 -               
35610 +
35611                 SEGFAULT();
35612         }
35613 -       
35614 +
35615         return -1;
35616  }
35617  
35618  #if 0
35619  static int fdevent_linux_rtsig_event_compress(fdevents *ev) {
35620         size_t j;
35621 -       
35622 +
35623         if (ev->used == 0) return 0;
35624         if (ev->unused.used != 0) return 0;
35625 -       
35626 +
35627         for (j = ev->used - 1; j + 1 > 0; j--) {
35628                 if (ev->pollfds[j].fd == -1) ev->used--;
35629         }
35630 -       
35631 -       
35632 +
35633 +
35634         return 0;
35635  }
35636  #endif
35637 @@ -78,21 +78,21 @@
35638         if (fde_ndx != -1) {
35639                 if (ev->pollfds[fde_ndx].fd == fd) {
35640                         ev->pollfds[fde_ndx].events = events;
35641 -                       
35642 +
35643                         return fde_ndx;
35644                 }
35645                 fprintf(stderr, "%s.%d: add: (%d, %d)\n", __FILE__, __LINE__, fde_ndx, ev->pollfds[fde_ndx].fd);
35646                 SEGFAULT();
35647         }
35648 -       
35649 +
35650         if (ev->unused.used > 0) {
35651                 int k = ev->unused.ptr[--ev->unused.used];
35652 -               
35653 +
35654                 ev->pollfds[k].fd = fd;
35655                 ev->pollfds[k].events = events;
35656  
35657                 bitset_set_bit(ev->sigbset, fd);
35658 -               
35659 +
35660                 return k;
35661         } else {
35662                 if (ev->size == 0) {
35663 @@ -102,12 +102,12 @@
35664                         ev->size += 16;
35665                         ev->pollfds = realloc(ev->pollfds, sizeof(*ev->pollfds) * ev->size);
35666                 }
35667 -               
35668 +
35669                 ev->pollfds[ev->used].fd = fd;
35670                 ev->pollfds[ev->used].events = events;
35671  
35672                 bitset_set_bit(ev->sigbset, fd);
35673 -       
35674 +
35675                 return ev->used++;
35676         }
35677  }
35678 @@ -115,20 +115,20 @@
35679  static int fdevent_linux_rtsig_poll(fdevents *ev, int timeout_ms) {
35680         struct timespec ts;
35681         int r;
35682 -       
35683 +
35684  #if 0
35685         fdevent_linux_rtsig_event_compress(ev);
35686  #endif
35687 -       
35688 +
35689         ev->in_sigio = 1;
35690 -               
35691 +
35692         ts.tv_sec =  timeout_ms / 1000;
35693         ts.tv_nsec = (timeout_ms % 1000) * 1000000;
35694         r = sigtimedwait(&(ev->sigset), &(ev->siginfo), &(ts));
35695 -               
35696 -       if (r == -1) { 
35697 +
35698 +       if (r == -1) {
35699                 if (errno == EAGAIN) return 0;
35700 -               return r; 
35701 +               return r;
35702         } else if (r == SIGIO) {
35703                 struct sigaction act;
35704  
35705 @@ -140,7 +140,7 @@
35706                 /* re-enable the signal queue */
35707                 act.sa_handler = SIG_DFL;
35708                 sigaction(ev->signum, &act, NULL);
35709 -               
35710 +
35711                 ev->in_sigio = 0;
35712                 r = poll(ev->pollfds, ev->used, timeout_ms);
35713  
35714 @@ -162,12 +162,12 @@
35715                 if (ev->siginfo.si_band == POLLERR) {
35716                         fprintf(stderr, "event: %d %02lx %02x %s\n", ev->siginfo.si_fd, ev->siginfo.si_band, errno, strerror(errno));
35717                 }
35718 -#  endif               
35719 +#  endif
35720                 if (ndx != 0) {
35721                         fprintf(stderr, "+\n");
35722                         return 0;
35723                 }
35724 -               
35725 +
35726                 return ev->siginfo.si_band & 0x3f;
35727         } else {
35728                 if (ndx >= ev->used) {
35729 @@ -188,13 +188,13 @@
35730  
35731  static int fdevent_linux_rtsig_fcntl_set(fdevents *ev, int fd) {
35732         static pid_t pid = 0;
35733 -       
35734 +
35735         if (pid == 0) pid = getpid();
35736 -       
35737 +
35738         if (-1 == fcntl(fd, F_SETSIG, ev->signum)) return -1;
35739 -       
35740 +
35741         if (-1 == fcntl(fd, F_SETOWN, (int) pid)) return -1;
35742 -       
35743 +
35744         return fcntl(fd, F_SETFL, O_ASYNC | O_NONBLOCK | O_RDWR);
35745  }
35746  
35747 @@ -205,12 +205,12 @@
35748                 return -1;
35749         } else {
35750                 size_t i;
35751 -               
35752 +
35753                 i = (ndx < 0) ? 0 : ndx + 1;
35754                 for (; i < ev->used; i++) {
35755                         if (ev->pollfds[i].revents) break;
35756                 }
35757 -               
35758 +
35759                 return i;
35760         }
35761  }
35762 @@ -219,34 +219,34 @@
35763         ev->type = FDEVENT_HANDLER_LINUX_RTSIG;
35764  #define SET(x) \
35765         ev->x = fdevent_linux_rtsig_##x;
35766 -       
35767 +
35768         SET(free);
35769         SET(poll);
35770 -       
35771 +
35772         SET(event_del);
35773         SET(event_add);
35774 -       
35775 +
35776         SET(event_next_fdndx);
35777         SET(fcntl_set);
35778         SET(event_get_fd);
35779         SET(event_get_revent);
35780 -       
35781 +
35782         ev->signum = SIGRTMIN + 1;
35783 -       
35784 +
35785         sigemptyset(&(ev->sigset));
35786         sigaddset(&(ev->sigset), ev->signum);
35787         sigaddset(&(ev->sigset), SIGIO);
35788         if (-1 == sigprocmask(SIG_BLOCK, &(ev->sigset), NULL)) {
35789                 fprintf(stderr, "%s.%d: sigprocmask failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n",
35790                         __FILE__, __LINE__, strerror(errno));
35791 -               
35792 +
35793                 return -1;
35794         }
35795 -       
35796 +
35797         ev->in_sigio = 1;
35798  
35799         ev->sigbset = bitset_init(ev->maxfds);
35800 -       
35801 +
35802         return 0;
35803  }
35804  #else
35805
35806 Property changes on: src/fdevent_linux_rtsig.c
35807 ___________________________________________________________________
35808 Name: svn:eol-style
35809    + native
35810
35811 Index: src/network_win32_send.c
35812 ===================================================================
35813 --- src/network_win32_send.c    (.../tags/lighttpd-1.4.11)      (revision 0)
35814 +++ src/network_win32_send.c    (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
35815 @@ -0,0 +1,234 @@
35816 +#include <sys/types.h>
35817 +#include <sys/stat.h>
35818 +
35819 +#include <errno.h>
35820 +#include <fcntl.h>
35821 +#include <string.h>
35822 +#include <stdlib.h>
35823 +#include <assert.h>
35824 +#include <stdio.h>
35825 +
35826 +#include "network.h"
35827 +#include "fdevent.h"
35828 +#include "log.h"
35829 +#include "stat_cache.h"
35830 +
35831 +#include "sys-socket.h"
35832 +#include "sys-files.h"
35833 +
35834 +#include "network_backends.h"
35835 +
35836 +#ifdef USE_WIN32_SEND
35837 +/**
35838 +* fill the chunkqueue will all the data that we can get
35839 +*
35840 +* this might be optimized into a readv() which uses the chunks
35841 +* as vectors
35842 +*/
35843 +
35844 +NETWORK_BACKEND_READ(win32recv) {
35845 +    int toread = 0;
35846 +    buffer *b;
35847 +    int r;
35848 +
35849 +       /* check how much we have to read */
35850 +       if (ioctlsocket(fd, FIONREAD, &toread)) {
35851 +               log_error_write(srv, __FILE__, __LINE__, "sd",
35852 +                               "ioctl failed: ",
35853 +                               fd);
35854 +               return NETWORK_STATUS_FATAL_ERROR;
35855 +       }
35856 +
35857 +       if (toread == 0) {
35858 +        /* win32 is strange */
35859 +        return con->bytes_read ? NETWORK_STATUS_CONNECTION_CLOSE : NETWORK_STATUS_WAIT_FOR_EVENT;
35860 +    }
35861 +
35862 +    /*
35863 +    * our chunk queue is quiet large already
35864 +    *
35865 +    * let's buffer it to disk
35866 +    */
35867 +
35868 +    b = chunkqueue_get_append_buffer(cq);
35869 +
35870 +    buffer_prepare_copy(b, toread + 1);
35871 +
35872 +    r = recv(fd, b->ptr, toread, 0);
35873 +
35874 +    /* something went wrong */
35875 +    if (r < 0) {
35876 +        errno = WSAGetLastError();
35877 +
35878 +        if (errno == WSAEWOULDBLOCK) return NETWORK_STATUS_WAIT_FOR_EVENT;
35879 +               if (errno == EINTR) {
35880 +                       /* we have been interrupted before we could read */
35881 +                       return NETWORK_STATUS_INTERRUPTED;
35882 +               }
35883 +
35884 +               if (errno == WSAECONNRESET) {
35885 +            /* expected for keep-alive */
35886 +            return NETWORK_STATUS_CONNECTION_CLOSE;
35887 +        }
35888 +
35889 +               log_error_write(srv, __FILE__, __LINE__, "ssdd",
35890 +            "connection closed - read failed: ",
35891 +            strerror(errno), con->fd, errno);
35892 +
35893 +        return NETWORK_STATUS_FATAL_ERROR;
35894 +    }
35895 +       /* this should be catched by the b > 0 above */
35896 +       assert(r);
35897 +       b->used += r + 1;
35898 +       b->ptr[b->used - 1] = '\0';
35899 +
35900 +    return NETWORK_STATUS_SUCCESS;
35901 +}
35902 +
35903 +NETWORK_BACKEND_WRITE(win32send) {
35904 +       chunk *c;
35905 +       size_t chunks_written = 0;
35906 +
35907 +       for(c = cq->first; c; c = c->next) {
35908 +               int chunk_finished = 0;
35909 +
35910 +               switch(c->type) {
35911 +               case MEM_CHUNK: {
35912 +                       char * offset;
35913 +                       size_t toSend;
35914 +                       ssize_t r;
35915 +
35916 +                       if (c->mem->used == 0) {
35917 +                               chunk_finished = 1;
35918 +                               break;
35919 +                       }
35920 +
35921 +                       offset = c->mem->ptr + c->offset;
35922 +                       toSend = c->mem->used - 1 - c->offset;
35923 +
35924 +                       if ((r = send(fd, offset, toSend, 0)) < 0) {
35925 +                    errno = WSAGetLastError();
35926 +
35927 +                switch(errno) {
35928 +                case WSAEWOULDBLOCK:
35929 +                    return NETWORK_STATUS_WAIT_FOR_EVENT;
35930 +                case WSAECONNABORTED:
35931 +                case WSAECONNRESET:
35932 +                    return NETWORK_STATUS_CONNECTION_CLOSE;
35933 +                default:
35934 +                    log_error_write(srv, __FILE__, __LINE__, "sdd", "send to socket:", errno, fd);
35935 +                    return NETWORK_STATUS_FATAL_ERROR;
35936 +                }
35937 +
35938 +                               return NETWORK_STATUS_FATAL_ERROR;
35939 +                       }
35940 +
35941 +                       c->offset += r;
35942 +                       cq->bytes_out += r;
35943 +
35944 +                       if (c->offset == (off_t)c->mem->used - 1) {
35945 +                               chunk_finished = 1;
35946 +                       }
35947 +
35948 +                       break;
35949 +               }
35950 +               case FILE_CHUNK: {
35951 +                       ssize_t r;
35952 +                       off_t offset;
35953 +
35954 +                       stat_cache_entry *sce = NULL;
35955 +
35956 +                       if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) {
35957 +                               log_error_write(srv, __FILE__, __LINE__, "sb",
35958 +                                               strerror(errno), c->file.name);
35959 +                               return NETWORK_STATUS_FATAL_ERROR;
35960 +                       }
35961 +
35962 +                       offset = c->file.start + c->offset;
35963 +
35964 +                       if (offset > sce->st.st_size) {
35965 +                               log_error_write(srv, __FILE__, __LINE__, "sb", "file was shrinked:", c->file.name);
35966 +
35967 +                               return NETWORK_STATUS_FATAL_ERROR;
35968 +                       }
35969 +
35970 +
35971 +            if (-1 == c->file.fd) {
35972 +                           if (-1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY|O_BINARY|O_SEQUENTIAL))) {
35973 +                                   log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
35974 +
35975 +                                   return NETWORK_STATUS_FATAL_ERROR;
35976 +                           }
35977 +            }
35978 +
35979 +            if (-1 == lseek(c->file.fd, offset, SEEK_SET)) {
35980 +                log_error_write(srv, __FILE__, __LINE__, "ss", "lseek failed: ", strerror(errno));
35981 +            }
35982 +
35983 +            while(1) {
35984 +                off_t haveRead = 0;
35985 +                int toSend;
35986 +
35987 +                /* only send 64k blocks */
35988 +                toSend = c->file.length - c->offset > 256 * 1024 ? 256 * 1024 : c->file.length - c->offset;
35989 +
35990 +                       buffer_prepare_copy(srv->tmp_buf, toSend);
35991 +
35992 +                           if (-1 == (haveRead = read(c->file.fd, srv->tmp_buf->ptr, toSend))) {
35993 +                                   log_error_write(srv, __FILE__, __LINE__, "ss", "read from file: ", strerror(errno));
35994 +
35995 +
35996 +                                   return NETWORK_STATUS_FATAL_ERROR;
35997 +                           }
35998 +
35999 +                           if (-1 == (r = send(fd, srv->tmp_buf->ptr, haveRead, 0))) {
36000 +                    errno = WSAGetLastError();
36001 +
36002 +                    switch(errno) {
36003 +                    case WSAEWOULDBLOCK:
36004 +                        return NETWORK_STATUS_WAIT_FOR_EVENT;
36005 +                    case WSAECONNABORTED:
36006 +                    case WSAECONNRESET:
36007 +                        return NETWORK_STATUS_CONNECTION_CLOSE;
36008 +                    default:
36009 +                                       log_error_write(srv, __FILE__, __LINE__, "sd", "send to socket:", errno);
36010 +
36011 +                                   return NETWORK_STATUS_FATAL_ERROR;
36012 +                    }
36013 +                       }
36014 +
36015 +                               c->offset += r;
36016 +                       cq->bytes_out += r;
36017 +
36018 +                if (r != haveRead) {
36019 +                    break;
36020 +                }
36021 +            }
36022 +
36023 +                       if (c->offset == c->file.length) {
36024 +                               chunk_finished = 1;
36025 +                       }
36026 +
36027 +                       break;
36028 +               }
36029 +               default:
36030 +
36031 +                       log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
36032 +
36033 +                       return NETWORK_STATUS_FATAL_ERROR;
36034 +               }
36035 +
36036 +               if (!chunk_finished) {
36037 +                       /* not finished yet */
36038 +
36039 +                       return NETWORK_STATUS_WAIT_FOR_EVENT;
36040 +               }
36041 +
36042 +               chunks_written++;
36043 +       }
36044 +    fprintf(stderr, "%s.%d: chunks_written: %d\r\n", __FILE__, __LINE__, chunks_written);
36045 +
36046 +       return NETWORK_STATUS_SUCCESS;
36047 +}
36048 +
36049 +#endif
36050
36051 Property changes on: src/network_win32_send.c
36052 ___________________________________________________________________
36053 Name: svn:eol-style
36054    + native
36055
36056 Index: src/data_string.c
36057 ===================================================================
36058 --- src/data_string.c   (.../tags/lighttpd-1.4.11)      (revision 1159)
36059 +++ src/data_string.c   (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
36060 @@ -17,16 +17,16 @@
36061  
36062  static void data_string_free(data_unset *d) {
36063         data_string *ds = (data_string *)d;
36064 -       
36065 +
36066         buffer_free(ds->key);
36067         buffer_free(ds->value);
36068 -       
36069 +
36070         free(d);
36071  }
36072  
36073  static void data_string_reset(data_unset *d) {
36074         data_string *ds = (data_string *)d;
36075 -       
36076 +
36077         /* reused array elements */
36078         buffer_reset(ds->key);
36079         buffer_reset(ds->value);
36080 @@ -35,23 +35,23 @@
36081  static int data_string_insert_dup(data_unset *dst, data_unset *src) {
36082         data_string *ds_dst = (data_string *)dst;
36083         data_string *ds_src = (data_string *)src;
36084 -       
36085 +
36086         if (ds_dst->value->used) {
36087                 buffer_append_string(ds_dst->value, ", ");
36088                 buffer_append_string_buffer(ds_dst->value, ds_src->value);
36089         } else {
36090                 buffer_copy_string_buffer(ds_dst->value, ds_src->value);
36091         }
36092 -       
36093 +
36094         src->free(src);
36095 -       
36096 +
36097         return 0;
36098  }
36099  
36100  static int data_response_insert_dup(data_unset *dst, data_unset *src) {
36101         data_string *ds_dst = (data_string *)dst;
36102         data_string *ds_src = (data_string *)src;
36103 -       
36104 +
36105         if (ds_dst->value->used) {
36106                 buffer_append_string(ds_dst->value, "\r\n");
36107                 buffer_append_string_buffer(ds_dst->value, ds_dst->key);
36108 @@ -60,9 +60,9 @@
36109         } else {
36110                 buffer_copy_string_buffer(ds_dst->value, ds_src->value);
36111         }
36112 -       
36113 +
36114         src->free(src);
36115 -       
36116 +
36117         return 0;
36118  }
36119  
36120 @@ -77,28 +77,28 @@
36121  
36122  data_string *data_string_init(void) {
36123         data_string *ds;
36124 -       
36125 +
36126         ds = calloc(1, sizeof(*ds));
36127         assert(ds);
36128 -       
36129 +
36130         ds->key = buffer_init();
36131         ds->value = buffer_init();
36132 -       
36133 +
36134         ds->copy = data_string_copy;
36135         ds->free = data_string_free;
36136         ds->reset = data_string_reset;
36137         ds->insert_dup = data_string_insert_dup;
36138         ds->print = data_string_print;
36139         ds->type = TYPE_STRING;
36140 -       
36141 +
36142         return ds;
36143  }
36144  
36145  data_string *data_response_init(void) {
36146         data_string *ds;
36147 -       
36148 +
36149         ds = data_string_init();
36150         ds->insert_dup = data_response_insert_dup;
36151 -       
36152 +
36153         return ds;
36154  }
36155
36156 Property changes on: src/data_string.c
36157 ___________________________________________________________________
36158 Name: svn:eol-style
36159    + native
36160
36161 Index: src/http-header-glue.c
36162 ===================================================================
36163 --- src/http-header-glue.c      (.../tags/lighttpd-1.4.11)      (revision 1159)
36164 +++ src/http-header-glue.c      (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
36165 @@ -45,20 +45,20 @@
36166  #   ifdef HAVE_STRUCT_SOCKADDR_STORAGE
36167  static size_t get_sa_len(const struct sockaddr *addr) {
36168         switch (addr->sa_family) {
36169 -               
36170 +
36171  #    ifdef AF_INET
36172         case AF_INET:
36173                 return (sizeof (struct sockaddr_in));
36174  #    endif
36175 -               
36176 +
36177  #    ifdef AF_INET6
36178         case AF_INET6:
36179                 return (sizeof (struct sockaddr_in6));
36180  #    endif
36181 -               
36182 +
36183         default:
36184                 return (sizeof (struct sockaddr));
36185 -               
36186 +
36187         }
36188  }
36189  #    define SA_LEN(addr)   (get_sa_len(addr))
36190 @@ -74,7 +74,7 @@
36191  
36192  int response_header_insert(server *srv, connection *con, const char *key, size_t keylen, const char *value, size_t vallen) {
36193         data_string *ds;
36194 -       
36195 +
36196         UNUSED(srv);
36197  
36198         if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
36199 @@ -82,32 +82,32 @@
36200         }
36201         buffer_copy_string_len(ds->key, key, keylen);
36202         buffer_copy_string_len(ds->value, value, vallen);
36203 -       
36204 +
36205         array_insert_unique(con->response.headers, (data_unset *)ds);
36206 -       
36207 +
36208         return 0;
36209  }
36210  
36211  int response_header_overwrite(server *srv, connection *con, const char *key, size_t keylen, const char *value, size_t vallen) {
36212         data_string *ds;
36213 -       
36214 +
36215         UNUSED(srv);
36216  
36217         /* if there already is a key by this name overwrite the value */
36218         if (NULL != (ds = (data_string *)array_get_element(con->response.headers, key))) {
36219                 buffer_copy_string(ds->value, value);
36220 -               
36221 +
36222                 return 0;
36223         }
36224 -       
36225 +
36226         return response_header_insert(srv, con, key, keylen, value, vallen);
36227  }
36228  
36229  int http_response_redirect_to_directory(server *srv, connection *con) {
36230         buffer *o;
36231 -       
36232 +
36233         o = buffer_init();
36234 -       
36235 +
36236         if (con->conf.is_ssl) {
36237                 buffer_copy_string(o, "https://");
36238         } else {
36239 @@ -123,36 +123,36 @@
36240  #endif
36241                 sock_addr our_addr;
36242                 socklen_t our_addr_len;
36243 -               
36244 +
36245                 our_addr_len = sizeof(our_addr);
36246 -               
36247 +
36248                 if (-1 == getsockname(con->fd, &(our_addr.plain), &our_addr_len)) {
36249                         con->http_status = 500;
36250 -                       
36251 +
36252                         log_error_write(srv, __FILE__, __LINE__, "ss",
36253                                         "can't get sockname", strerror(errno));
36254 -                       
36255 +
36256                         buffer_free(o);
36257                         return 0;
36258                 }
36259 -               
36260 -               
36261 +
36262 +
36263                 /* Lookup name: secondly try to get hostname for bind address */
36264                 switch(our_addr.plain.sa_family) {
36265  #ifdef HAVE_IPV6
36266                 case AF_INET6:
36267 -                       if (0 != getnameinfo((const struct sockaddr *)(&our_addr.ipv6), 
36268 -                                            SA_LEN((const struct sockaddr *)&our_addr.ipv6), 
36269 +                       if (0 != getnameinfo((const struct sockaddr *)(&our_addr.ipv6),
36270 +                                            SA_LEN((const struct sockaddr *)&our_addr.ipv6),
36271                                              hbuf, sizeof(hbuf), NULL, 0, 0)) {
36272 -                               
36273 +
36274                                 char dst[INET6_ADDRSTRLEN];
36275 -                               
36276 +
36277                                 log_error_write(srv, __FILE__, __LINE__,
36278                                                 "SSSS", "NOTICE: getnameinfo failed: ",
36279                                                 strerror(errno), ", using ip-address instead");
36280 -                               
36281 -                               buffer_append_string(o, 
36282 -                                                    inet_ntop(AF_INET6, (char *)&our_addr.ipv6.sin6_addr, 
36283 +
36284 +                               buffer_append_string(o,
36285 +                                                    inet_ntop(AF_INET6, (char *)&our_addr.ipv6.sin6_addr,
36286                                                                dst, sizeof(dst)));
36287                         } else {
36288                                 buffer_append_string(o, hbuf);
36289 @@ -164,7 +164,7 @@
36290                                 log_error_write(srv, __FILE__, __LINE__,
36291                                                 "SdSS", "NOTICE: gethostbyaddr failed: ",
36292                                                 h_errno, ", using ip-address instead");
36293 -                               
36294 +
36295                                 buffer_append_string(o, inet_ntoa(our_addr.ipv4.sin_addr));
36296                         } else {
36297                                 buffer_append_string(o, he->h_name);
36298 @@ -173,12 +173,12 @@
36299                 default:
36300                         log_error_write(srv, __FILE__, __LINE__,
36301                                         "S", "ERROR: unsupported address-type");
36302 -                       
36303 +
36304                         buffer_free(o);
36305                         return -1;
36306                 }
36307 -               
36308 -               if (!((con->conf.is_ssl == 0 && srv->srvconf.port == 80) || 
36309 +
36310 +               if (!((con->conf.is_ssl == 0 && srv->srvconf.port == 80) ||
36311                       (con->conf.is_ssl == 1 && srv->srvconf.port == 443))) {
36312                         buffer_append_string(o, ":");
36313                         buffer_append_long(o, srv->srvconf.port);
36314 @@ -190,41 +190,41 @@
36315                 buffer_append_string(o, "?");
36316                 buffer_append_string_buffer(o, con->uri.query);
36317         }
36318 -       
36319 +
36320         response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(o));
36321 -       
36322 +
36323         con->http_status = 301;
36324         con->file_finished = 1;
36325 -       
36326 +
36327         buffer_free(o);
36328 -       
36329 +
36330         return 0;
36331  }
36332  
36333  buffer * strftime_cache_get(server *srv, time_t last_mod) {
36334         struct tm *tm;
36335         size_t i;
36336 -               
36337 +
36338         for (i = 0; i < FILE_CACHE_MAX; i++) {
36339                 /* found cache-entry */
36340                 if (srv->mtime_cache[i].mtime == last_mod) return srv->mtime_cache[i].str;
36341 -                               
36342 +
36343                 /* found empty slot */
36344                 if (srv->mtime_cache[i].mtime == 0) break;
36345         }
36346 -       
36347 +
36348         if (i == FILE_CACHE_MAX) {
36349                 i = 0;
36350         }
36351 -               
36352 +
36353         srv->mtime_cache[i].mtime = last_mod;
36354         buffer_prepare_copy(srv->mtime_cache[i].str, 1024);
36355         tm = gmtime(&(srv->mtime_cache[i].mtime));
36356 -       srv->mtime_cache[i].str->used = strftime(srv->mtime_cache[i].str->ptr, 
36357 +       srv->mtime_cache[i].str->used = strftime(srv->mtime_cache[i].str->ptr,
36358                                                  srv->mtime_cache[i].str->size - 1,
36359                                                  "%a, %d %b %Y %H:%M:%S GMT", tm);
36360         srv->mtime_cache[i].str->used++;
36361 -       
36362 +
36363         return srv->mtime_cache[i].str;
36364  }
36365  
36366 @@ -239,56 +239,60 @@
36367          *    request. That is, if no entity tags match, then the server MUST NOT
36368          *    return a 304 (Not Modified) response.
36369          */
36370 -       
36371 +
36372         /* last-modified handling */
36373         if (con->request.http_if_none_match) {
36374                 if (etag_is_equal(con->physical.etag, con->request.http_if_none_match)) {
36375 -                       if (con->request.http_method == HTTP_METHOD_GET || 
36376 +                       if (con->request.http_method == HTTP_METHOD_GET ||
36377                             con->request.http_method == HTTP_METHOD_HEAD) {
36378 -                               
36379 +
36380                                 /* check if etag + last-modified */
36381                                 if (con->request.http_if_modified_since) {
36382                                         size_t used_len;
36383                                         char *semicolon;
36384 -                                       
36385 +
36386                                         if (NULL == (semicolon = strchr(con->request.http_if_modified_since, ';'))) {
36387                                                 used_len = strlen(con->request.http_if_modified_since);
36388                                         } else {
36389                                                 used_len = semicolon - con->request.http_if_modified_since;
36390                                         }
36391 -                                       
36392 +
36393                                         if (0 == strncmp(con->request.http_if_modified_since, mtime->ptr, used_len)) {
36394                                                 con->http_status = 304;
36395                                                 return HANDLER_FINISHED;
36396                                         } else {
36397 +#ifdef HAVE_STRPTIME
36398                                                 char buf[sizeof("Sat, 23 Jul 2005 21:20:01 GMT")];
36399 +                                               time_t t_header, t_file;
36400 +                                               struct tm tm;
36401  
36402 -                                               /* convert to timestamp */
36403 -                                               if (used_len < sizeof(buf)) {
36404 -                                                       time_t t_header, t_file;
36405 -                                                       struct tm tm;
36406 -                                                       
36407 -                                                       strncpy(buf, con->request.http_if_modified_since, used_len);
36408 -                                                       buf[used_len] = '\0';
36409 -                                                       
36410 -                                                       strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm);
36411 -                                                       t_header = mktime(&tm);
36412 -                                                       
36413 -                                                       strptime(mtime->ptr, "%a, %d %b %Y %H:%M:%S GMT", &tm);
36414 -                                                       t_file = mktime(&tm);
36415 +                                               /* check if we can safely copy the string */
36416 +                                               if (used_len >= sizeof(buf)) {
36417 +                                                       log_error_write(srv, __FILE__, __LINE__, "ssdd",
36418 +                                                                       "DEBUG: Last-Modified check failed as the received timestamp was too long:",
36419 +                                                                       con->request.http_if_modified_since, used_len, sizeof(buf) - 1);
36420  
36421 -                                                       if (t_file > t_header) {
36422 -                                                               con->http_status = 304;
36423 -                                                               return HANDLER_FINISHED;
36424 -                                                       }
36425 -                                               } else {
36426 -                                                       log_error_write(srv, __FILE__, __LINE__, "ssdd", 
36427 -                                                                       "DEBUG: Last-Modified check failed as the received timestamp was too long:", 
36428 -                                                                       con->request.http_if_modified_since, used_len, sizeof(buf) - 1);
36429 -                                                       
36430                                                         con->http_status = 412;
36431                                                         return HANDLER_FINISHED;
36432                                                 }
36433 +
36434 +
36435 +                                               strncpy(buf, con->request.http_if_modified_since, used_len);
36436 +                                               buf[used_len] = '\0';
36437 +
36438 +                                               strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm);
36439 +                                               t_header = mktime(&tm);
36440 +
36441 +                                               strptime(mtime->ptr, "%a, %d %b %Y %H:%M:%S GMT", &tm);
36442 +                                               t_file = mktime(&tm);
36443 +
36444 +                                               if (t_file > t_header) return HANDLER_GO_ON;
36445 +
36446 +                                               con->http_status = 304;
36447 +                                               return HANDLER_FINISHED;
36448 +#else
36449 +                        return HANDLER_GO_ON;
36450 +#endif
36451                                         }
36452                                 } else {
36453                                         con->http_status = 304;
36454 @@ -302,16 +306,41 @@
36455         } else if (con->request.http_if_modified_since) {
36456                 size_t used_len;
36457                 char *semicolon;
36458 -               
36459 +
36460                 if (NULL == (semicolon = strchr(con->request.http_if_modified_since, ';'))) {
36461                         used_len = strlen(con->request.http_if_modified_since);
36462                 } else {
36463                         used_len = semicolon - con->request.http_if_modified_since;
36464                 }
36465 -               
36466 +
36467                 if (0 == strncmp(con->request.http_if_modified_since, mtime->ptr, used_len)) {
36468                         con->http_status = 304;
36469                         return HANDLER_FINISHED;
36470 +               } else {
36471 +#ifdef HAVE_STRPTIME
36472 +                       char buf[sizeof("Sat, 23 Jul 2005 21:20:01 GMT")];
36473 +                       time_t t_header, t_file;
36474 +                       struct tm tm;
36475 +
36476 +                       /* convert to timestamp */
36477 +                       if (used_len >= sizeof(buf)) return HANDLER_GO_ON;
36478 +
36479 +                       strncpy(buf, con->request.http_if_modified_since, used_len);
36480 +                       buf[used_len] = '\0';
36481 +
36482 +                       strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm);
36483 +                       t_header = mktime(&tm);
36484 +
36485 +                       strptime(mtime->ptr, "%a, %d %b %Y %H:%M:%S GMT", &tm);
36486 +                       t_file = mktime(&tm);
36487 +
36488 +                       if (t_file > t_header) return HANDLER_GO_ON;
36489 +
36490 +                       con->http_status = 304;
36491 +                       return HANDLER_FINISHED;
36492 +#else
36493 +            return HANDLER_GO_ON;
36494 +#endif
36495                 }
36496         }
36497  
36498
36499 Property changes on: src/http-header-glue.c
36500 ___________________________________________________________________
36501 Name: svn:eol-style
36502    + native
36503
36504 Index: src/mod_evasive.c
36505 ===================================================================
36506 --- src/mod_evasive.c   (.../tags/lighttpd-1.4.11)      (revision 1159)
36507 +++ src/mod_evasive.c   (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
36508 @@ -31,100 +31,97 @@
36509  
36510  typedef struct {
36511         PLUGIN_DATA;
36512 -       
36513 +
36514         plugin_config **config_storage;
36515 -       
36516 -       plugin_config conf; 
36517 +
36518 +       plugin_config conf;
36519  } plugin_data;
36520  
36521  INIT_FUNC(mod_evasive_init) {
36522         plugin_data *p;
36523 -       
36524 +
36525         p = calloc(1, sizeof(*p));
36526 -       
36527 +
36528         return p;
36529  }
36530  
36531  FREE_FUNC(mod_evasive_free) {
36532         plugin_data *p = p_d;
36533 -       
36534 +
36535         UNUSED(srv);
36536  
36537         if (!p) return HANDLER_GO_ON;
36538 -       
36539 +
36540         if (p->config_storage) {
36541                 size_t i;
36542                 for (i = 0; i < srv->config_context->used; i++) {
36543                         plugin_config *s = p->config_storage[i];
36544 -                                               
36545 +
36546                         free(s);
36547                 }
36548                 free(p->config_storage);
36549         }
36550 -       
36551 +
36552         free(p);
36553 -       
36554 +
36555         return HANDLER_GO_ON;
36556  }
36557  
36558  SETDEFAULTS_FUNC(mod_evasive_set_defaults) {
36559         plugin_data *p = p_d;
36560         size_t i = 0;
36561 -       
36562 -       config_values_t cv[] = { 
36563 +
36564 +       config_values_t cv[] = {
36565                 { "evasive.max-conns-per-ip",    NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },
36566                 { NULL,                          NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
36567         };
36568 -       
36569 +
36570         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
36571 -       
36572 +
36573         for (i = 0; i < srv->config_context->used; i++) {
36574                 plugin_config *s;
36575 -               
36576 +
36577                 s = calloc(1, sizeof(plugin_config));
36578                 s->max_conns       = 0;
36579 -               
36580 +
36581                 cv[0].destination = &(s->max_conns);
36582 -               
36583 +
36584                 p->config_storage[i] = s;
36585 -       
36586 +
36587                 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
36588                         return HANDLER_ERROR;
36589                 }
36590         }
36591 -       
36592 +
36593         return HANDLER_GO_ON;
36594  }
36595  
36596 -#define PATCH(x) \
36597 -       p->conf.x = s->x;
36598  static int mod_evasive_patch_connection(server *srv, connection *con, plugin_data *p) {
36599         size_t i, j;
36600         plugin_config *s = p->config_storage[0];
36601  
36602 -       PATCH(max_conns);
36603 -       
36604 +       PATCH_OPTION(max_conns);
36605 +
36606         /* skip the first, the global context */
36607         for (i = 1; i < srv->config_context->used; i++) {
36608                 data_config *dc = (data_config *)srv->config_context->data[i];
36609                 s = p->config_storage[i];
36610 -               
36611 +
36612                 /* condition didn't match */
36613                 if (!config_check_cond(srv, con, dc)) continue;
36614 -               
36615 +
36616                 /* merge config */
36617                 for (j = 0; j < dc->value->used; j++) {
36618                         data_unset *du = dc->value->data[j];
36619 -                       
36620 +
36621                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("evasive.max-conns-per-ip"))) {
36622 -                               PATCH(max_conns);
36623 +                               PATCH_OPTION(max_conns);
36624                         }
36625                 }
36626         }
36627 -       
36628 +
36629         return 0;
36630  }
36631 -#undef PATCH
36632  
36633  URIHANDLER_FUNC(mod_evasive_uri_handler) {
36634         plugin_data *p = p_d;
36635 @@ -132,10 +129,10 @@
36636         size_t j;
36637  
36638         if (con->uri.path->used == 0) return HANDLER_GO_ON;
36639 -       
36640 +
36641         mod_evasive_patch_connection(srv, con, p);
36642 -       
36643 -       /* no limit set, nothing to block */    
36644 +
36645 +       /* no limit set, nothing to block */
36646         if (p->conf.max_conns == 0) return HANDLER_GO_ON;
36647  
36648         for (j = 0; j < srv->conns->used; j++) {
36649 @@ -147,7 +144,7 @@
36650                 if (c->dst_addr.ipv4.sin_addr.s_addr == con->dst_addr.ipv4.sin_addr.s_addr &&
36651                     c->state > CON_STATE_REQUEST_END) {
36652                         conns_by_ip++;
36653 -       
36654 +
36655                         if (conns_by_ip > p->conf.max_conns) {
36656                                 log_error_write(srv, __FILE__, __LINE__, "ss",
36657                                         inet_ntop_cache_get_ip(srv, &(con->dst_addr)),
36658 @@ -158,7 +155,7 @@
36659                         }
36660                 }
36661         }
36662 -       
36663 +
36664         return HANDLER_GO_ON;
36665  }
36666  
36667 @@ -166,13 +163,13 @@
36668  int mod_evasive_plugin_init(plugin *p) {
36669         p->version     = LIGHTTPD_VERSION_ID;
36670         p->name        = buffer_init_string("evasive");
36671 -       
36672 +
36673         p->init        = mod_evasive_init;
36674         p->set_defaults = mod_evasive_set_defaults;
36675         p->handle_uri_clean  = mod_evasive_uri_handler;
36676         p->cleanup     = mod_evasive_free;
36677 -       
36678 +
36679         p->data        = NULL;
36680 -       
36681 +
36682         return 0;
36683  }
36684
36685 Property changes on: src/mod_evasive.c
36686 ___________________________________________________________________
36687 Name: svn:eol-style
36688    + native
36689
36690 Index: src/mod_setenv.c
36691 ===================================================================
36692 --- src/mod_setenv.c    (.../tags/lighttpd-1.4.11)      (revision 1159)
36693 +++ src/mod_setenv.c    (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
36694 @@ -18,25 +18,25 @@
36695  typedef struct {
36696         array *request_header;
36697         array *response_header;
36698 -       
36699 +
36700         array *environment;
36701  } plugin_config;
36702  
36703  typedef struct {
36704         PLUGIN_DATA;
36705 -       
36706 +
36707         plugin_config **config_storage;
36708 -       
36709 -       plugin_config conf; 
36710 +
36711 +       plugin_config conf;
36712  } plugin_data;
36713  
36714  static handler_ctx * handler_ctx_init() {
36715         handler_ctx * hctx;
36716 -       
36717 +
36718         hctx = calloc(1, sizeof(*hctx));
36719 -       
36720 +
36721         hctx->handled = 0;
36722 -       
36723 +
36724         return hctx;
36725  }
36726  
36727 @@ -48,36 +48,36 @@
36728  /* init the plugin data */
36729  INIT_FUNC(mod_setenv_init) {
36730         plugin_data *p;
36731 -       
36732 +
36733         p = calloc(1, sizeof(*p));
36734 -       
36735 +
36736         return p;
36737  }
36738  
36739  /* detroy the plugin data */
36740  FREE_FUNC(mod_setenv_free) {
36741         plugin_data *p = p_d;
36742 -       
36743 +
36744         UNUSED(srv);
36745  
36746         if (!p) return HANDLER_GO_ON;
36747 -       
36748 +
36749         if (p->config_storage) {
36750                 size_t i;
36751                 for (i = 0; i < srv->config_context->used; i++) {
36752                         plugin_config *s = p->config_storage[i];
36753 -                       
36754 +
36755                         array_free(s->request_header);
36756                         array_free(s->response_header);
36757                         array_free(s->environment);
36758 -                       
36759 +
36760                         free(s);
36761                 }
36762                 free(p->config_storage);
36763         }
36764 -       
36765 +
36766         free(p);
36767 -       
36768 +
36769         return HANDLER_GO_ON;
36770  }
36771  
36772 @@ -86,86 +86,83 @@
36773  SETDEFAULTS_FUNC(mod_setenv_set_defaults) {
36774         plugin_data *p = p_d;
36775         size_t i = 0;
36776 -       
36777 -       config_values_t cv[] = { 
36778 +
36779 +       config_values_t cv[] = {
36780                 { "setenv.add-request-header",  NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
36781                 { "setenv.add-response-header", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
36782                 { "setenv.add-environment",     NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 2 */
36783                 { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
36784         };
36785 -       
36786 +
36787         if (!p) return HANDLER_ERROR;
36788 -       
36789 +
36790         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
36791 -       
36792 +
36793         for (i = 0; i < srv->config_context->used; i++) {
36794                 plugin_config *s;
36795 -               
36796 +
36797                 s = calloc(1, sizeof(plugin_config));
36798                 s->request_header   = array_init();
36799                 s->response_header  = array_init();
36800                 s->environment      = array_init();
36801 -               
36802 +
36803                 cv[0].destination = s->request_header;
36804                 cv[1].destination = s->response_header;
36805                 cv[2].destination = s->environment;
36806 -               
36807 +
36808                 p->config_storage[i] = s;
36809 -       
36810 +
36811                 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
36812                         return HANDLER_ERROR;
36813                 }
36814         }
36815 -       
36816 +
36817         return HANDLER_GO_ON;
36818  }
36819  
36820 -#define PATCH(x) \
36821 -       p->conf.x = s->x;
36822  static int mod_setenv_patch_connection(server *srv, connection *con, plugin_data *p) {
36823         size_t i, j;
36824         plugin_config *s = p->config_storage[0];
36825 -       
36826 -       PATCH(request_header);
36827 -       PATCH(response_header);
36828 -       PATCH(environment);
36829 -       
36830 +
36831 +       PATCH_OPTION(request_header);
36832 +       PATCH_OPTION(response_header);
36833 +       PATCH_OPTION(environment);
36834 +
36835         /* skip the first, the global context */
36836         for (i = 1; i < srv->config_context->used; i++) {
36837                 data_config *dc = (data_config *)srv->config_context->data[i];
36838                 s = p->config_storage[i];
36839 -               
36840 +
36841                 /* condition didn't match */
36842                 if (!config_check_cond(srv, con, dc)) continue;
36843 -               
36844 +
36845                 /* merge config */
36846                 for (j = 0; j < dc->value->used; j++) {
36847                         data_unset *du = dc->value->data[j];
36848 -                       
36849 +
36850                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("setenv.add-request-header"))) {
36851 -                               PATCH(request_header);
36852 +                               PATCH_OPTION(request_header);
36853                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("setenv.add-response-header"))) {
36854 -                               PATCH(response_header);
36855 +                               PATCH_OPTION(response_header);
36856                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("setenv.add-environment"))) {
36857 -                               PATCH(environment);
36858 +                               PATCH_OPTION(environment);
36859                         }
36860                 }
36861         }
36862 -       
36863 +
36864         return 0;
36865  }
36866 -#undef PATCH
36867  
36868  URIHANDLER_FUNC(mod_setenv_uri_handler) {
36869         plugin_data *p = p_d;
36870         size_t k;
36871         handler_ctx *hctx;
36872 -       
36873 +
36874         if (con->plugin_ctx[p->id]) {
36875                 hctx = con->plugin_ctx[p->id];
36876         } else {
36877                 hctx = handler_ctx_init();
36878 -                               
36879 +
36880                 con->plugin_ctx[p->id] = hctx;
36881         }
36882  
36883 @@ -180,52 +177,52 @@
36884         for (k = 0; k < p->conf.request_header->used; k++) {
36885                 data_string *ds = (data_string *)p->conf.request_header->data[k];
36886                 data_string *ds_dst;
36887 -               
36888 +
36889                 if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
36890                         ds_dst = data_string_init();
36891                 }
36892 -               
36893 +
36894                 buffer_copy_string_buffer(ds_dst->key, ds->key);
36895                 buffer_copy_string_buffer(ds_dst->value, ds->value);
36896 -               
36897 +
36898                 array_insert_unique(con->request.headers, (data_unset *)ds_dst);
36899         }
36900 -       
36901 +
36902         for (k = 0; k < p->conf.environment->used; k++) {
36903                 data_string *ds = (data_string *)p->conf.environment->data[k];
36904                 data_string *ds_dst;
36905 -               
36906 +
36907                 if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->environment, TYPE_STRING))) {
36908                         ds_dst = data_string_init();
36909                 }
36910 -               
36911 +
36912                 buffer_copy_string_buffer(ds_dst->key, ds->key);
36913                 buffer_copy_string_buffer(ds_dst->value, ds->value);
36914 -               
36915 +
36916                 array_insert_unique(con->environment, (data_unset *)ds_dst);
36917         }
36918 -       
36919 +
36920         for (k = 0; k < p->conf.response_header->used; k++) {
36921                 data_string *ds = (data_string *)p->conf.response_header->data[k];
36922 -               
36923 +
36924                 response_header_insert(srv, con, CONST_BUF_LEN(ds->key), CONST_BUF_LEN(ds->value));
36925         }
36926 -       
36927 +
36928         /* not found */
36929         return HANDLER_GO_ON;
36930  }
36931  
36932  REQUESTDONE_FUNC(mod_setenv_reset) {
36933         plugin_data *p = p_d;
36934 -       
36935 +
36936         UNUSED(srv);
36937 -       
36938 +
36939         if (con->plugin_ctx[p->id]) {
36940                 handler_ctx_free(con->plugin_ctx[p->id]);
36941                 con->plugin_ctx[p->id] = NULL;
36942         }
36943  
36944 -       return HANDLER_GO_ON;   
36945 +       return HANDLER_GO_ON;
36946  }
36947  
36948  /* this function is called at dlopen() time and inits the callbacks */
36949 @@ -233,15 +230,15 @@
36950  int mod_setenv_plugin_init(plugin *p) {
36951         p->version     = LIGHTTPD_VERSION_ID;
36952         p->name        = buffer_init_string("setenv");
36953 -       
36954 +
36955         p->init        = mod_setenv_init;
36956         p->handle_uri_clean  = mod_setenv_uri_handler;
36957         p->set_defaults  = mod_setenv_set_defaults;
36958         p->cleanup     = mod_setenv_free;
36959 -       
36960 +
36961         p->handle_request_done  = mod_setenv_reset;
36962  
36963         p->data        = NULL;
36964 -       
36965 +
36966         return 0;
36967  }
36968
36969 Property changes on: src/mod_setenv.c
36970 ___________________________________________________________________
36971 Name: svn:eol-style
36972    + native
36973
36974 Index: src/mod_indexfile.c
36975 ===================================================================
36976 --- src/mod_indexfile.c (.../tags/lighttpd-1.4.11)      (revision 1159)
36977 +++ src/mod_indexfile.c (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
36978 @@ -20,51 +20,51 @@
36979  
36980  typedef struct {
36981         PLUGIN_DATA;
36982 -       
36983 +
36984         buffer *tmp_buf;
36985 -       
36986 +
36987         plugin_config **config_storage;
36988 -       
36989 -       plugin_config conf; 
36990 +
36991 +       plugin_config conf;
36992  } plugin_data;
36993  
36994  /* init the plugin data */
36995  INIT_FUNC(mod_indexfile_init) {
36996         plugin_data *p;
36997 -       
36998 +
36999         p = calloc(1, sizeof(*p));
37000 -       
37001 +
37002         p->tmp_buf = buffer_init();
37003 -       
37004 +
37005         return p;
37006  }
37007  
37008  /* detroy the plugin data */
37009  FREE_FUNC(mod_indexfile_free) {
37010         plugin_data *p = p_d;
37011 -       
37012 +
37013         UNUSED(srv);
37014  
37015         if (!p) return HANDLER_GO_ON;
37016 -       
37017 +
37018         if (p->config_storage) {
37019                 size_t i;
37020                 for (i = 0; i < srv->config_context->used; i++) {
37021                         plugin_config *s = p->config_storage[i];
37022  
37023                         if (!s) continue;
37024 -                       
37025 +
37026                         array_free(s->indexfiles);
37027 -                       
37028 +
37029                         free(s);
37030                 }
37031                 free(p->config_storage);
37032         }
37033 -       
37034 +
37035         buffer_free(p->tmp_buf);
37036 -       
37037 +
37038         free(p);
37039 -       
37040 +
37041         return HANDLER_GO_ON;
37042  }
37043  
37044 @@ -73,131 +73,128 @@
37045  SETDEFAULTS_FUNC(mod_indexfile_set_defaults) {
37046         plugin_data *p = p_d;
37047         size_t i = 0;
37048 -       
37049 -       config_values_t cv[] = { 
37050 +
37051 +       config_values_t cv[] = {
37052                 { "index-file.names",           NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
37053                 { "server.indexfiles",          NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
37054                 { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
37055         };
37056 -       
37057 +
37058         if (!p) return HANDLER_ERROR;
37059 -       
37060 +
37061         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
37062 -       
37063 +
37064         for (i = 0; i < srv->config_context->used; i++) {
37065                 plugin_config *s;
37066 -               
37067 +
37068                 s = calloc(1, sizeof(plugin_config));
37069                 s->indexfiles    = array_init();
37070 -               
37071 +
37072                 cv[0].destination = s->indexfiles;
37073                 cv[1].destination = s->indexfiles; /* old name for [0] */
37074 -               
37075 +
37076                 p->config_storage[i] = s;
37077 -       
37078 +
37079                 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
37080                         return HANDLER_ERROR;
37081                 }
37082         }
37083 -       
37084 +
37085         return HANDLER_GO_ON;
37086  }
37087  
37088 -#define PATCH(x) \
37089 -       p->conf.x = s->x;
37090  static int mod_indexfile_patch_connection(server *srv, connection *con, plugin_data *p) {
37091         size_t i, j;
37092         plugin_config *s = p->config_storage[0];
37093 -       
37094 -       PATCH(indexfiles);
37095 -       
37096 +
37097 +       PATCH_OPTION(indexfiles);
37098 +
37099         /* skip the first, the global context */
37100         for (i = 1; i < srv->config_context->used; i++) {
37101                 data_config *dc = (data_config *)srv->config_context->data[i];
37102                 s = p->config_storage[i];
37103 -               
37104 +
37105                 /* condition didn't match */
37106                 if (!config_check_cond(srv, con, dc)) continue;
37107 -               
37108 +
37109                 /* merge config */
37110                 for (j = 0; j < dc->value->used; j++) {
37111                         data_unset *du = dc->value->data[j];
37112 -                       
37113 +
37114                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.indexfiles"))) {
37115 -                               PATCH(indexfiles);
37116 +                               PATCH_OPTION(indexfiles);
37117                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("index-file.names"))) {
37118 -                               PATCH(indexfiles);
37119 +                               PATCH_OPTION(indexfiles);
37120                         }
37121                 }
37122         }
37123 -       
37124 +
37125         return 0;
37126  }
37127 -#undef PATCH
37128  
37129  URIHANDLER_FUNC(mod_indexfile_subrequest) {
37130         plugin_data *p = p_d;
37131         size_t k;
37132         stat_cache_entry *sce = NULL;
37133 -       
37134 +
37135         if (con->uri.path->used == 0) return HANDLER_GO_ON;
37136         if (con->uri.path->ptr[con->uri.path->used - 2] != '/') return HANDLER_GO_ON;
37137 -       
37138 +
37139         mod_indexfile_patch_connection(srv, con, p);
37140 -       
37141 +
37142         if (con->conf.log_request_handling) {
37143                 log_error_write(srv, __FILE__, __LINE__,  "s",  "-- handling the request as Indexfile");
37144                 log_error_write(srv, __FILE__, __LINE__,  "sb", "URI          :", con->uri.path);
37145         }
37146 -       
37147 +
37148         /* indexfile */
37149         for (k = 0; k < p->conf.indexfiles->used; k++) {
37150                 data_string *ds = (data_string *)p->conf.indexfiles->data[k];
37151 -               
37152 +
37153                 if (ds->value && ds->value->ptr[0] == '/') {
37154 -                       /* if the index-file starts with a prefix as use this file as 
37155 +                       /* if the index-file starts with a prefix as use this file as
37156                          * index-generator */
37157                         buffer_copy_string_buffer(p->tmp_buf, con->physical.doc_root);
37158                 } else {
37159                         buffer_copy_string_buffer(p->tmp_buf, con->physical.path);
37160                 }
37161                 buffer_append_string_buffer(p->tmp_buf, ds->value);
37162 -               
37163 +
37164                 if (HANDLER_ERROR == stat_cache_get_entry(srv, con, p->tmp_buf, &sce)) {
37165                         if (errno == EACCES) {
37166                                 con->http_status = 403;
37167                                 buffer_reset(con->physical.path);
37168 -                               
37169 +
37170                                 return HANDLER_FINISHED;
37171                         }
37172 -                       
37173 +
37174                         if (errno != ENOENT &&
37175                             errno != ENOTDIR) {
37176                                 /* we have no idea what happend. let's tell the user so. */
37177 -                               
37178 +
37179                                 con->http_status = 500;
37180 -                               
37181 +
37182                                 log_error_write(srv, __FILE__, __LINE__, "ssbsb",
37183                                                 "file not found ... or so: ", strerror(errno),
37184                                                 con->uri.path,
37185                                                 "->", con->physical.path);
37186 -                               
37187 +
37188                                 buffer_reset(con->physical.path);
37189 -                               
37190 +
37191                                 return HANDLER_FINISHED;
37192                         }
37193                         continue;
37194                 }
37195 -                       
37196 +
37197                 /* rewrite uri.path to the real path (/ -> /index.php) */
37198                 buffer_append_string_buffer(con->uri.path, ds->value);
37199                 buffer_copy_string_buffer(con->physical.path, p->tmp_buf);
37200 -               
37201 +
37202                 /* fce is already set up a few lines above */
37203 -               
37204 +
37205                 return HANDLER_GO_ON;
37206         }
37207 -       
37208 +
37209         /* not found */
37210         return HANDLER_GO_ON;
37211  }
37212 @@ -207,13 +204,13 @@
37213  int mod_indexfile_plugin_init(plugin *p) {
37214         p->version     = LIGHTTPD_VERSION_ID;
37215         p->name        = buffer_init_string("indexfile");
37216 -       
37217 +
37218         p->init        = mod_indexfile_init;
37219         p->handle_subrequest_start = mod_indexfile_subrequest;
37220         p->set_defaults  = mod_indexfile_set_defaults;
37221         p->cleanup     = mod_indexfile_free;
37222 -       
37223 +
37224         p->data        = NULL;
37225 -       
37226 +
37227         return 0;
37228  }
37229
37230 Property changes on: src/mod_indexfile.c
37231 ___________________________________________________________________
37232 Name: svn:eol-style
37233    + native
37234
37235 Index: src/mod_uploadprogress.c
37236 ===================================================================
37237 --- src/mod_uploadprogress.c    (.../tags/lighttpd-1.4.11)      (revision 1159)
37238 +++ src/mod_uploadprogress.c    (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
37239 @@ -13,7 +13,7 @@
37240  
37241  /**
37242   * this is a uploadprogress for a lighttpd plugin
37243 - * 
37244 + *
37245   */
37246  
37247  typedef struct {
37248 @@ -23,7 +23,7 @@
37249  
37250  typedef struct {
37251         connection_map_entry **ptr;
37252 -       
37253 +
37254         size_t used;
37255         size_t size;
37256  } connection_map;
37257 @@ -36,26 +36,26 @@
37258  
37259  typedef struct {
37260         PLUGIN_DATA;
37261 -       
37262 +
37263         connection_map *con_map;
37264 -       
37265 +
37266         plugin_config **config_storage;
37267 -       
37268 -       plugin_config conf; 
37269 +
37270 +       plugin_config conf;
37271  } plugin_data;
37272  
37273  /**
37274 - * 
37275 + *
37276   * connection maps
37277 - * 
37278 + *
37279   */
37280  
37281  /* init the plugin data */
37282  connection_map *connection_map_init() {
37283         connection_map *cm;
37284 -       
37285 +
37286         cm = calloc(1, sizeof(*cm));
37287 -       
37288 +
37289         return cm;
37290  }
37291  
37292 @@ -63,22 +63,22 @@
37293         size_t i;
37294         for (i = 0; i < cm->size; i++) {
37295                 connection_map_entry *cme = cm->ptr[i];
37296 -               
37297 +
37298                 if (!cme) break;
37299 -               
37300 +
37301                 if (cme->con_id) {
37302                         buffer_free(cme->con_id);
37303                 }
37304                 free(cme);
37305         }
37306 -       
37307 +
37308         free(cm);
37309  }
37310  
37311  int connection_map_insert(connection_map *cm, connection *con, buffer *con_id) {
37312         connection_map_entry *cme;
37313         size_t i;
37314 -       
37315 +
37316         if (cm->size == 0) {
37317                 cm->size = 16;
37318                 cm->ptr = malloc(cm->size * sizeof(*(cm->ptr)));
37319 @@ -92,7 +92,7 @@
37320                         cm->ptr[i] = NULL;
37321                 }
37322         }
37323 -       
37324 +
37325         if (cm->ptr[cm->used]) {
37326                 /* is already alloced, just reuse it */
37327                 cme = cm->ptr[cm->used];
37328 @@ -102,21 +102,21 @@
37329         cme->con_id = buffer_init();
37330         buffer_copy_string_buffer(cme->con_id, con_id);
37331         cme->con = con;
37332 -       
37333 +
37334         cm->ptr[cm->used++] = cme;
37335 -       
37336 +
37337         return 0;
37338  }
37339  
37340  connection *connection_map_get_connection(connection_map *cm, buffer *con_id) {
37341         size_t i;
37342 -       
37343 +
37344         for (i = 0; i < cm->used; i++) {
37345                 connection_map_entry *cme = cm->ptr[i];
37346 -               
37347 +
37348                 if (buffer_is_equal(cme->con_id, con_id)) {
37349                         /* found connection */
37350 -                       
37351 +
37352                         return cme->con;
37353                 }
37354         }
37355 @@ -125,66 +125,66 @@
37356  
37357  int connection_map_remove_connection(connection_map *cm, connection *con) {
37358         size_t i;
37359 -       
37360 +
37361         for (i = 0; i < cm->used; i++) {
37362                 connection_map_entry *cme = cm->ptr[i];
37363 -               
37364 +
37365                 if (cme->con == con) {
37366                         /* found connection */
37367 -                       
37368 +
37369                         buffer_reset(cme->con_id);
37370                         cme->con = NULL;
37371 -                       
37372 +
37373                         cm->used--;
37374 -                       
37375 +
37376                         /* swap positions with the last entry */
37377                         if (cm->used) {
37378                                 cm->ptr[i] = cm->ptr[cm->used];
37379                                 cm->ptr[cm->used] = cme;
37380                         }
37381 -                       
37382 +
37383                         return 1;
37384                 }
37385         }
37386 -       
37387 +
37388         return 0;
37389  }
37390  
37391  /* init the plugin data */
37392  INIT_FUNC(mod_uploadprogress_init) {
37393         plugin_data *p;
37394 -       
37395 +
37396         p = calloc(1, sizeof(*p));
37397 -       
37398 +
37399         p->con_map = connection_map_init();
37400 -       
37401 +
37402         return p;
37403  }
37404  
37405  /* detroy the plugin data */
37406  FREE_FUNC(mod_uploadprogress_free) {
37407         plugin_data *p = p_d;
37408 -       
37409 +
37410         UNUSED(srv);
37411  
37412         if (!p) return HANDLER_GO_ON;
37413 -       
37414 +
37415         if (p->config_storage) {
37416                 size_t i;
37417                 for (i = 0; i < srv->config_context->used; i++) {
37418                         plugin_config *s = p->config_storage[i];
37419 -                       
37420 +
37421                         buffer_free(s->progress_url);
37422 -                       
37423 +
37424                         free(s);
37425                 }
37426                 free(p->config_storage);
37427         }
37428 -       
37429 +
37430         connection_map_free(p->con_map);
37431 -       
37432 +
37433         free(p);
37434 -       
37435 +
37436         return HANDLER_GO_ON;
37437  }
37438  
37439 @@ -193,80 +193,77 @@
37440  SETDEFAULTS_FUNC(mod_uploadprogress_set_defaults) {
37441         plugin_data *p = p_d;
37442         size_t i = 0;
37443 -       
37444 -       config_values_t cv[] = { 
37445 +
37446 +       config_values_t cv[] = {
37447                 { "upload-progress.progress-url", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
37448                 { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
37449         };
37450 -       
37451 +
37452         if (!p) return HANDLER_ERROR;
37453 -       
37454 +
37455         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
37456 -       
37457 +
37458         for (i = 0; i < srv->config_context->used; i++) {
37459                 plugin_config *s;
37460 -               
37461 +
37462                 s = calloc(1, sizeof(plugin_config));
37463                 s->progress_url    = buffer_init();
37464 -               
37465 +
37466                 cv[0].destination = s->progress_url;
37467 -               
37468 +
37469                 p->config_storage[i] = s;
37470 -       
37471 +
37472                 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
37473                         return HANDLER_ERROR;
37474                 }
37475         }
37476 -       
37477 +
37478         return HANDLER_GO_ON;
37479  }
37480  
37481 -#define PATCH(x) \
37482 -       p->conf.x = s->x;
37483  static int mod_uploadprogress_patch_connection(server *srv, connection *con, plugin_data *p) {
37484         size_t i, j;
37485         plugin_config *s = p->config_storage[0];
37486 -       
37487 -       PATCH(progress_url);
37488 -       
37489 +
37490 +       PATCH_OPTION(progress_url);
37491 +
37492         /* skip the first, the global context */
37493         for (i = 1; i < srv->config_context->used; i++) {
37494                 data_config *dc = (data_config *)srv->config_context->data[i];
37495                 s = p->config_storage[i];
37496 -               
37497 +
37498                 /* condition didn't match */
37499                 if (!config_check_cond(srv, con, dc)) continue;
37500 -               
37501 +
37502                 /* merge config */
37503                 for (j = 0; j < dc->value->used; j++) {
37504                         data_unset *du = dc->value->data[j];
37505 -                       
37506 +
37507                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("upload-progress.progress-url"))) {
37508 -                               PATCH(progress_url);
37509 +                               PATCH_OPTION(progress_url);
37510                         }
37511                 }
37512         }
37513 -       
37514 +
37515         return 0;
37516  }
37517 -#undef PATCH
37518  
37519  /**
37520 - * 
37521 + *
37522   * the idea:
37523 - * 
37524 - * for the first request we check if it is a post-request 
37525 - * 
37526 + *
37527 + * for the first request we check if it is a post-request
37528 + *
37529   * if no, move out, don't care about them
37530 - * 
37531 - * if yes, take the connection structure and register it locally 
37532 + *
37533 + * if yes, take the connection structure and register it locally
37534   * in the progress-struct together with an session-id (md5 ... )
37535 - * 
37536 + *
37537   * if the connections closes, cleanup the entry in the progress-struct
37538 - * 
37539 + *
37540   * a second request can now get the info about the size of the upload,
37541   * the received bytes
37542 - * 
37543 + *
37544   */
37545  
37546  URIHANDLER_FUNC(mod_uploadprogress_uri_handler) {
37547 @@ -275,21 +272,21 @@
37548         data_string *ds;
37549         buffer *b;
37550         connection *post_con = NULL;
37551 -       
37552 +
37553         UNUSED(srv);
37554  
37555         if (con->uri.path->used == 0) return HANDLER_GO_ON;
37556 -       
37557 +
37558         mod_uploadprogress_patch_connection(srv, con, p);
37559 -       
37560 +
37561         /* check if this is a POST request */
37562         switch(con->request.http_method) {
37563         case HTTP_METHOD_POST:
37564                 /* the request has to contain a 32byte ID */
37565 -               
37566 +
37567                 if (NULL == (ds = (data_string *)array_get_element(con->request.headers, "X-Progress-ID"))) {
37568                         if (!buffer_is_empty(con->uri.query)) {
37569 -                               /* perhaps the POST request is using the querystring to pass the X-Progress-ID */ 
37570 +                               /* perhaps the POST request is using the querystring to pass the X-Progress-ID */
37571                                 b = con->uri.query;
37572                         } else {
37573                                 return HANDLER_GO_ON;
37574 @@ -297,34 +294,34 @@
37575                 } else {
37576                         b = ds->value;
37577                 }
37578 -               
37579 +
37580                 if (b->used != 32 + 1) {
37581                         log_error_write(srv, __FILE__, __LINE__, "sd",
37582                                         "len of progress-id != 32:", b->used - 1);
37583                         return HANDLER_GO_ON;
37584                 }
37585 -               
37586 +
37587                 for (i = 0; i < b->used - 1; i++) {
37588                         char c = b->ptr[i];
37589 -                       
37590 +
37591                         if (!light_isxdigit(c)) {
37592                                 log_error_write(srv, __FILE__, __LINE__, "sb",
37593                                                 "non-xdigit in progress-id:", b);
37594                                 return HANDLER_GO_ON;
37595                         }
37596                 }
37597 -               
37598 +
37599                 connection_map_insert(p->con_map, con, b);
37600 -               
37601 +
37602                 return HANDLER_GO_ON;
37603         case HTTP_METHOD_GET:
37604                 if (!buffer_is_equal(con->uri.path, p->conf.progress_url)) {
37605                         return HANDLER_GO_ON;
37606                 }
37607 -               
37608 +
37609                 if (NULL == (ds = (data_string *)array_get_element(con->request.headers, "X-Progress-ID"))) {
37610                         if (!buffer_is_empty(con->uri.query)) {
37611 -                               /* perhaps the GET request is using the querystring to pass the X-Progress-ID */ 
37612 +                               /* perhaps the GET request is using the querystring to pass the X-Progress-ID */
37613                                 b = con->uri.query;
37614                         } else {
37615                                 return HANDLER_GO_ON;
37616 @@ -332,23 +329,23 @@
37617                 } else {
37618                         b = ds->value;
37619                 }
37620 -               
37621 +
37622                 if (b->used != 32 + 1) {
37623                         log_error_write(srv, __FILE__, __LINE__, "sd",
37624                                         "len of progress-id != 32:", b->used - 1);
37625                         return HANDLER_GO_ON;
37626                 }
37627 -               
37628 +
37629                 for (i = 0; i < b->used - 1; i++) {
37630                         char c = b->ptr[i];
37631 -                       
37632 +
37633                         if (!light_isxdigit(c)) {
37634                                 log_error_write(srv, __FILE__, __LINE__, "sb",
37635                                                 "non-xdigit in progress-id:", b);
37636                                 return HANDLER_GO_ON;
37637                         }
37638                 }
37639 -               
37640 +
37641                 buffer_reset(con->physical.path);
37642  
37643                 con->file_started = 1;
37644 @@ -362,21 +359,21 @@
37645                                         "ID no known:", b);
37646  
37647                         b = chunkqueue_get_append_buffer(con->write_queue);
37648 -                       
37649 +
37650                         BUFFER_APPEND_STRING_CONST(b, "starting");
37651  
37652                         return HANDLER_FINISHED;
37653                 }
37654 -               
37655 +
37656                 response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml"));
37657 -               
37658 +
37659                 /* just an attempt the force the IE/proxies to NOT cache the request ... doesn't help :( */
37660                 response_header_overwrite(srv, con, CONST_STR_LEN("Pragma"), CONST_STR_LEN("no-cache"));
37661                 response_header_overwrite(srv, con, CONST_STR_LEN("Expires"), CONST_STR_LEN("Thu, 19 Nov 1981 08:52:00 GMT"));
37662                 response_header_overwrite(srv, con, CONST_STR_LEN("Cache-Control"), CONST_STR_LEN("no-store, no-cache, must-revalidate, post-check=0, pre-check=0"));
37663 -               
37664 +
37665                 b = chunkqueue_get_append_buffer(con->write_queue);
37666 -               
37667 +
37668                 /* prepare XML */
37669                 BUFFER_COPY_STRING_CONST(b, "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>");
37670                 BUFFER_APPEND_STRING_CONST(b, "<upload>");
37671 @@ -387,7 +384,7 @@
37672                 buffer_append_off_t(b, post_con->request_content_queue->bytes_in);
37673                 BUFFER_APPEND_STRING_CONST(b, "</received>");
37674                 BUFFER_APPEND_STRING_CONST(b, "</upload>");
37675 -               
37676 +
37677                 log_error_write(srv, __FILE__, __LINE__, "sb", "...", b);
37678  
37679                 return HANDLER_FINISHED;
37680 @@ -400,15 +397,15 @@
37681  
37682  REQUESTDONE_FUNC(mod_uploadprogress_request_done) {
37683         plugin_data *p = p_d;
37684 -       
37685 +
37686         UNUSED(srv);
37687  
37688         if (con->uri.path->used == 0) return HANDLER_GO_ON;
37689 -       
37690 +
37691         if (connection_map_remove_connection(p->con_map, con)) {
37692                 /* removed */
37693         }
37694 -       
37695 +
37696         return HANDLER_GO_ON;
37697  }
37698  
37699 @@ -417,14 +414,14 @@
37700  int mod_uploadprogress_plugin_init(plugin *p) {
37701         p->version     = LIGHTTPD_VERSION_ID;
37702         p->name        = buffer_init_string("uploadprogress");
37703 -       
37704 +
37705         p->init        = mod_uploadprogress_init;
37706         p->handle_uri_clean  = mod_uploadprogress_uri_handler;
37707         p->handle_request_done  = mod_uploadprogress_request_done;
37708         p->set_defaults  = mod_uploadprogress_set_defaults;
37709         p->cleanup     = mod_uploadprogress_free;
37710 -       
37711 +
37712         p->data        = NULL;
37713 -       
37714 +
37715         return 0;
37716  }
37717
37718 Property changes on: src/mod_uploadprogress.c
37719 ___________________________________________________________________
37720 Name: svn:eol-style
37721    + native
37722
37723 Index: src/http_resp.c
37724 ===================================================================
37725 --- src/http_resp.c     (.../tags/lighttpd-1.4.11)      (revision 0)
37726 +++ src/http_resp.c     (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
37727 @@ -0,0 +1,263 @@
37728 +#include <string.h>
37729 +#include <stdlib.h>
37730 +#include <stdio.h>
37731 +#include <assert.h>
37732 +
37733 +#include "http_resp.h"
37734 +#include "http_resp_parser.h"
37735 +
37736 +/* declare prototypes for the parser */
37737 +void *http_resp_parserAlloc(void *(*mallocProc)(size_t));
37738 +void http_resp_parserFree(void *p,  void (*freeProc)(void*));
37739 +void http_resp_parserTrace(FILE *TraceFILE, char *zTracePrompt);
37740 +void http_resp_parser(void *, int, buffer *, http_resp_ctx_t *);
37741 +
37742 +typedef struct {
37743 +       chunkqueue *cq;
37744 +
37745 +       chunk *c; /* current chunk in the chunkqueue */
37746 +    size_t offset; /* current offset in current chunk */
37747 +
37748 +    chunk *lookup_c;
37749 +    size_t lookup_offset;
37750 +
37751 +    int is_key;
37752 +    int is_statusline;
37753 +} http_resp_tokenizer_t;
37754 +
37755 +http_resp *http_response_init(void) {
37756 +    http_resp *resp = calloc(1, sizeof(*resp));
37757 +
37758 +    resp->reason = buffer_init();
37759 +    resp->headers = array_init();
37760 +
37761 +    return resp;
37762 +}
37763 +
37764 +void http_response_reset(http_resp *resp) {
37765 +    if (!resp) return;
37766 +
37767 +    buffer_reset(resp->reason);
37768 +    array_reset(resp->headers);
37769 +
37770 +}
37771 +
37772 +void http_response_free(http_resp *resp) {
37773 +    if (!resp) return;
37774 +
37775 +    buffer_free(resp->reason);
37776 +    array_free(resp->headers);
37777 +
37778 +    free(resp);
37779 +}
37780 +
37781 +static int http_resp_get_next_char(http_resp_tokenizer_t *t, unsigned char *c) {
37782 +    if (t->offset == t->c->mem->used - 1) {
37783 +        /* end of chunk, open next chunk */
37784 +
37785 +        if (!t->c->next) return -1;
37786 +
37787 +        t->c = t->c->next;
37788 +        t->offset = 0;
37789 +    }
37790 +
37791 +    *c = t->c->mem->ptr[t->offset++];
37792 +
37793 +    t->lookup_offset = t->offset;
37794 +    t->lookup_c = t->c;
37795 +
37796 +#if 0
37797 +    fprintf(stderr, "%s.%d: get: %c (%d) at offset: %d\r\n", __FILE__, __LINE__, *c > 31 ? *c : ' ', *c, t->offset - 1);
37798 +#endif
37799 +
37800 +    return 0;
37801 +}
37802 +
37803 +static int http_resp_lookup_next_char(http_resp_tokenizer_t *t, unsigned char *c) {
37804 +    if (t->lookup_offset == t->lookup_c->mem->used - 1) {
37805 +        /* end of chunk, open next chunk */
37806 +
37807 +        if (!t->lookup_c->next) return -1;
37808 +
37809 +        t->lookup_c = t->lookup_c->next;
37810 +        t->lookup_offset = 0;
37811 +    }
37812 +
37813 +    *c = t->lookup_c->mem->ptr[t->lookup_offset++];
37814 +#if 0
37815 +    fprintf(stderr, "%s.%d: lookup: %c (%d) at offset: %d\r\n", __FILE__, __LINE__, *c > 31 ? *c : ' ', *c, t->lookup_offset - 1);
37816 +#endif
37817 +
37818 +    return 0;
37819 +}
37820 +
37821 +
37822 +static int http_resp_tokenizer(
37823 +    http_resp_tokenizer_t *t,
37824 +    int *token_id,
37825 +    buffer *token
37826 +) {
37827 +    unsigned char c;
37828 +    int tid = 0;
37829 +
37830 +    /* push the token to the parser */
37831 +
37832 +    while (tid == 0 && 0 == http_resp_get_next_char(t, &c)) {
37833 +        switch (c) {
37834 +        case ':':
37835 +            tid = TK_COLON;
37836 +
37837 +            t->is_key = 0;
37838 +
37839 +            break;
37840 +        case ' ':
37841 +        case '\t':
37842 +            /* ignore WS */
37843 +
37844 +            break;
37845 +        case '\r':
37846 +            if (0 != http_resp_lookup_next_char(t, &c)) return -1;
37847 +
37848 +            if (c == '\n') {
37849 +                tid = TK_CRLF;
37850 +
37851 +                t->c = t->lookup_c;
37852 +                t->offset = t->lookup_offset;
37853 +
37854 +                t->is_statusline = 0;
37855 +                t->is_key = 1;
37856 +            } else {
37857 +                fprintf(stderr, "%s.%d: CR with out LF\r\n", __FILE__, __LINE__);
37858 +                return -1;
37859 +            }
37860 +            break;
37861 +        case '\n':
37862 +            tid = TK_CRLF;
37863 +
37864 +            t->is_statusline = 0;
37865 +            t->is_key = 1;
37866 +
37867 +            break;
37868 +        default:
37869 +            while (c >= 32 && c != 127 && c != 255) {
37870 +                if (t->is_statusline) {
37871 +                       if (c == ':') {t->is_statusline = 0; break; } /* this is not a status line by a real header */
37872 +                    if (c == 32) break; /* the space is a splitter in the statusline */
37873 +                } else {
37874 +                    if (t->is_key) {
37875 +                        if (c == ':') break; /* the : is the splitter between key and value */
37876 +                    }
37877 +                }
37878 +                if (0 != http_resp_lookup_next_char(t, &c)) return -1;
37879 +            }
37880 +
37881 +            if (t->c == t->lookup_c &&
37882 +                t->offset == t->lookup_offset + 1) {
37883 +
37884 +                fprintf(stderr, "%s.%d: invalid char in string\n", __FILE__, __LINE__);
37885 +                return -1;
37886 +            }
37887 +
37888 +            tid = TK_STRING;
37889 +
37890 +            /* the lookup points to the first invalid char */
37891 +            t->lookup_offset--;
37892 +
37893 +            /* no overlapping string */
37894 +            if (t->c == t->lookup_c) {
37895 +                buffer_copy_string_len(token, t->c->mem->ptr + t->offset - 1, t->lookup_offset - t->offset + 1);
37896 +            } else {
37897 +                /* first chunk */
37898 +                buffer_copy_string_len(token, t->c->mem->ptr + t->offset - 1, t->c->mem->used - t->offset);
37899 +
37900 +                /* chunks in the middle */
37901 +                for (t->c = t->c->next; t->c != t->lookup_c; t->c = t->c->next) {
37902 +                    buffer_append_string_buffer(token, t->c->mem);
37903 +                    t->offset = t->c->mem->used - 1;
37904 +                }
37905 +
37906 +                /* last chunk */
37907 +                buffer_append_string_len(token, t->c->mem->ptr, t->lookup_offset);
37908 +            }
37909 +
37910 +            t->offset = t->lookup_offset;
37911 +
37912 +            break;
37913 +        }
37914 +       }
37915 +
37916 +    if (tid) {
37917 +               *token_id = tid;
37918 +
37919 +        return 1;
37920 +    }
37921 +
37922 +    return -1;
37923 +}
37924 +
37925 +parse_status_t http_response_parse_cq(chunkqueue *cq, http_resp *resp) {
37926 +    http_resp_tokenizer_t t;
37927 +       void *pParser = NULL;
37928 +       int token_id = 0;
37929 +       buffer *token = NULL;
37930 +       http_resp_ctx_t context;
37931 +    parse_status_t ret = PARSE_UNSET;
37932 +    int last_token_id = 0;
37933 +
37934 +       t.cq = cq;
37935 +    t.c = cq->first;
37936 +    t.offset = t.c->offset;
37937 +    t.is_key = 0;
37938 +    t.is_statusline = 1;
37939 +
37940 +       context.ok = 1;
37941 +    context.errmsg = buffer_init();
37942 +    context.resp = resp;
37943 +
37944 +       pParser = http_resp_parserAlloc( malloc );
37945 +       token = buffer_init();
37946 +    /* http_resp_parserTrace(stderr, "http-response: "); */
37947 +
37948 +       while((1 == http_resp_tokenizer(&t, &token_id, token)) && context.ok) {
37949 +               http_resp_parser(pParser, token_id, token, &context);
37950 +
37951 +               token = buffer_init();
37952 +
37953 +        if (last_token_id == TK_CRLF &&
37954 +            token_id == TK_CRLF) break;
37955 +
37956 +        last_token_id = token_id;
37957 +       }
37958 +
37959 +    /* oops, the parser failed */
37960 +    if (context.ok == 0) {
37961 +        ret = PARSE_ERROR;
37962 +
37963 +        fprintf(stderr, "%s.%d: parsing failed at: ...%20s\r\n",
37964 +            __FILE__, __LINE__, t.c->mem->ptr + t.offset);
37965 +    }
37966 +
37967 +       http_resp_parser(pParser, 0, token, &context);
37968 +       http_resp_parserFree(pParser, free );
37969 +
37970 +    if (context.ok == 0) {
37971 +        /* we are missing the some tokens */
37972 +
37973 +        if (ret == PARSE_UNSET) ret = PARSE_NEED_MORE;
37974 +    } else {
37975 +        chunk *c;
37976 +
37977 +        for (c = cq->first; c != t.c; c = c->next) {
37978 +            c->offset = c->mem->used - 1;
37979 +        }
37980 +
37981 +        c->offset = t.offset;
37982 +
37983 +        ret = PARSE_SUCCESS;
37984 +    }
37985 +
37986 +    buffer_free(token);
37987 +
37988 +    return ret;
37989 +}
37990 +
37991
37992 Property changes on: src/http_resp.c
37993 ___________________________________________________________________
37994 Name: svn:eol-style
37995    + native
37996
37997 Index: src/data_fastcgi.c
37998 ===================================================================
37999 --- src/data_fastcgi.c  (.../tags/lighttpd-1.4.11)      (revision 1159)
38000 +++ src/data_fastcgi.c  (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
38001 @@ -17,53 +17,53 @@
38002  
38003  static void data_fastcgi_free(data_unset *d) {
38004         data_fastcgi *ds = (data_fastcgi *)d;
38005 -       
38006 +
38007         buffer_free(ds->key);
38008         buffer_free(ds->host);
38009 -       
38010 +
38011         free(d);
38012  }
38013  
38014  static void data_fastcgi_reset(data_unset *d) {
38015         data_fastcgi *ds = (data_fastcgi *)d;
38016 -       
38017 +
38018         buffer_reset(ds->key);
38019         buffer_reset(ds->host);
38020 -       
38021 +
38022  }
38023  
38024  static int data_fastcgi_insert_dup(data_unset *dst, data_unset *src) {
38025         UNUSED(dst);
38026  
38027         src->free(src);
38028 -       
38029 +
38030         return 0;
38031  }
38032  
38033  static void data_fastcgi_print(const data_unset *d, int depth) {
38034         data_fastcgi *ds = (data_fastcgi *)d;
38035         UNUSED(depth);
38036 -       
38037 +
38038         fprintf(stderr, "fastcgi(%s)", ds->host->ptr);
38039  }
38040  
38041  
38042  data_fastcgi *data_fastcgi_init(void) {
38043         data_fastcgi *ds;
38044 -       
38045 +
38046         ds = calloc(1, sizeof(*ds));
38047 -       
38048 +
38049         ds->key = buffer_init();
38050         ds->host = buffer_init();
38051         ds->port = 0;
38052         ds->is_disabled = 0;
38053 -       
38054 +
38055         ds->copy = data_fastcgi_copy;
38056         ds->free = data_fastcgi_free;
38057         ds->reset = data_fastcgi_reset;
38058         ds->insert_dup = data_fastcgi_insert_dup;
38059         ds->print = data_fastcgi_print;
38060         ds->type = TYPE_FASTCGI;
38061 -       
38062 +
38063         return ds;
38064  }
38065
38066 Property changes on: src/data_fastcgi.c
38067 ___________________________________________________________________
38068 Name: svn:eol-style
38069    + native
38070
38071
38072 Property changes on: src/mod_ssi_exprparser.h
38073 ___________________________________________________________________
38074 Name: svn:eol-style
38075    + native
38076
38077 Index: src/http_resp.h
38078 ===================================================================
38079 --- src/http_resp.h     (.../tags/lighttpd-1.4.11)      (revision 0)
38080 +++ src/http_resp.h     (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
38081 @@ -0,0 +1,34 @@
38082 +#ifndef _HTTP_RESP_H_
38083 +#define _HTTP_RESP_H_
38084 +
38085 +#include "array.h"
38086 +#include "chunk.h"
38087 +
38088 +typedef enum {
38089 +    PARSE_UNSET,
38090 +    PARSE_SUCCESS,
38091 +    PARSE_ERROR,
38092 +    PARSE_NEED_MORE
38093 +} parse_status_t;
38094 +
38095 +typedef struct {
38096 +    int protocol;   /* http/1.0, http/1.1 */
38097 +    int status;     /* e.g. 200 */
38098 +    buffer *reason; /* e.g. Ok */
38099 +    array *headers;
38100 +} http_resp;
38101 +
38102 +typedef struct {
38103 +       int     ok;
38104 +    buffer *errmsg;
38105 +
38106 +    http_resp *resp;
38107 +} http_resp_ctx_t;
38108 +
38109 +http_resp *http_response_init(void);
38110 +void http_response_free(http_resp *resp);
38111 +void http_response_reset(http_resp *resp);
38112 +
38113 +parse_status_t http_response_parse_cq(chunkqueue *cq, http_resp *http_response);
38114 +
38115 +#endif
38116
38117 Property changes on: src/http_resp.h
38118 ___________________________________________________________________
38119 Name: svn:eol-style
38120    + native
38121
38122 Index: src/mod_fastcgi.c
38123 ===================================================================
38124 --- src/mod_fastcgi.c   (.../tags/lighttpd-1.4.11)      (revision 1159)
38125 +++ src/mod_fastcgi.c   (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
38126 @@ -1,5 +1,4 @@
38127  #include <sys/types.h>
38128 -#include <unistd.h>
38129  #include <errno.h>
38130  #include <fcntl.h>
38131  #include <string.h>
38132 @@ -24,7 +23,7 @@
38133  #include "inet_ntop_cache.h"
38134  #include "stat_cache.h"
38135  
38136 -#include <fastcgi.h>
38137 +#include "fastcgi.h"
38138  #include <stdio.h>
38139  
38140  #ifdef HAVE_SYS_FILIO_H
38141 @@ -32,7 +31,11 @@
38142  #endif
38143  
38144  #include "sys-socket.h"
38145 +#include "sys-files.h"
38146 +#include "sys-strings.h"
38147 +#include "sys-process.h"
38148  
38149 +#include "http_resp.h"
38150  
38151  #ifndef UNIX_PATH_MAX
38152  # define UNIX_PATH_MAX 108
38153 @@ -45,14 +48,13 @@
38154  #include <sys/wait.h>
38155  #endif
38156  
38157 -
38158  /*
38159 - * 
38160 + *
38161   * TODO:
38162 - * 
38163 + *
38164   * - add timeout for a connect to a non-fastcgi process
38165   *   (use state_timestamp + state)
38166 - * 
38167 + *
38168   */
38169  
38170  typedef struct fcgi_proc {
38171 @@ -61,7 +63,7 @@
38172         unsigned port;  /* config.port + pno */
38173  
38174         buffer *connection_name; /* either tcp:<host>:<port> or unix:<socket> for debuggin purposes */
38175 -       
38176 +
38177         pid_t pid;   /* PID of the spawned process (0 if not spawned locally) */
38178  
38179  
38180 @@ -70,20 +72,20 @@
38181         time_t last_used; /* see idle_timeout */
38182         size_t requests;  /* see max_requests */
38183         struct fcgi_proc *prev, *next; /* see first */
38184 -       
38185 +
38186         time_t disabled_until; /* this proc is disabled until, use something else until than */
38187 -       
38188 +
38189         int is_local;
38190  
38191 -       enum { 
38192 +       enum {
38193                 PROC_STATE_UNSET,    /* init-phase */
38194                 PROC_STATE_RUNNING,  /* alive */
38195 -               PROC_STATE_OVERLOADED, /* listen-queue is full, 
38196 +               PROC_STATE_OVERLOADED, /* listen-queue is full,
38197                                           don't send something to this proc for the next 2 seconds */
38198                 PROC_STATE_DIED_WAIT_FOR_PID, /* */
38199                 PROC_STATE_DIED,     /* marked as dead, should be restarted */
38200                 PROC_STATE_KILLED    /* was killed as we don't have the load anymore */
38201 -       } state; 
38202 +       } state;
38203  } fcgi_proc;
38204  
38205  typedef struct {
38206 @@ -94,20 +96,20 @@
38207          * sorted by lowest load
38208          *
38209          * whenever a job is done move it up in the list
38210 -        * until it is sorted, move it down as soon as the 
38211 +        * until it is sorted, move it down as soon as the
38212          * job is started
38213          */
38214 -       fcgi_proc *first; 
38215 -       fcgi_proc *unused_procs; 
38216 +       fcgi_proc *first;
38217 +       fcgi_proc *unused_procs;
38218  
38219 -       /* 
38220 +       /*
38221          * spawn at least min_procs, at max_procs.
38222          *
38223 -        * as soon as the load of the first entry 
38224 +        * as soon as the load of the first entry
38225          * is max_load_per_proc we spawn a new one
38226 -        * and add it to the first entry and give it 
38227 +        * and add it to the first entry and give it
38228          * the load
38229 -        * 
38230 +        *
38231          */
38232  
38233         unsigned short min_procs;
38234 @@ -119,44 +121,44 @@
38235  
38236         /*
38237          * kick the process from the list if it was not
38238 -        * used for idle_timeout until min_procs is 
38239 +        * used for idle_timeout until min_procs is
38240          * reached. this helps to get the processlist
38241          * small again we had a small peak load.
38242          *
38243          */
38244 -       
38245 +
38246         unsigned short idle_timeout;
38247 -       
38248 +
38249         /*
38250          * time after a disabled remote connection is tried to be re-enabled
38251 -        * 
38252 -        * 
38253 +        *
38254 +        *
38255          */
38256 -       
38257 +
38258         unsigned short disable_time;
38259  
38260         /*
38261          * same fastcgi processes get a little bit larger
38262 -        * than wanted. max_requests_per_proc kills a 
38263 +        * than wanted. max_requests_per_proc kills a
38264          * process after a number of handled requests.
38265          *
38266          */
38267         size_t max_requests_per_proc;
38268 -       
38269  
38270 +
38271         /* config */
38272  
38273 -       /* 
38274 -        * host:port 
38275 +       /*
38276 +        * host:port
38277          *
38278 -        * if host is one of the local IP adresses the 
38279 +        * if host is one of the local IP adresses the
38280          * whole connection is local
38281          *
38282          * if tcp/ip should be used host AND port have
38283 -        * to be specified 
38284 -        * 
38285 -        */ 
38286 -       buffer *host; 
38287 +        * to be specified
38288 +        *
38289 +        */
38290 +       buffer *host;
38291         unsigned short port;
38292  
38293         /*
38294 @@ -169,7 +171,7 @@
38295          */
38296         buffer *unixsocket;
38297  
38298 -       /* if socket is local we can start the fastcgi 
38299 +       /* if socket is local we can start the fastcgi
38300          * process ourself
38301          *
38302          * bin-path is the path to the binary
38303 @@ -177,19 +179,19 @@
38304          * check min_procs and max_procs for the number
38305          * of process to start-up
38306          */
38307 -       buffer *bin_path; 
38308 -       
38309 -       /* bin-path is set bin-environment is taken to 
38310 +       buffer *bin_path;
38311 +
38312 +       /* bin-path is set bin-environment is taken to
38313          * create the environement before starting the
38314          * FastCGI process
38315 -        * 
38316 +        *
38317          */
38318         array *bin_env;
38319 -       
38320 +
38321         array *bin_env_copy;
38322 -       
38323 +
38324         /*
38325 -        * docroot-translation between URL->phys and the 
38326 +        * docroot-translation between URL->phys and the
38327          * remote host
38328          *
38329          * reasons:
38330 @@ -208,7 +210,7 @@
38331         unsigned short mode;
38332  
38333         /*
38334 -        * check_local tell you if the phys file is stat()ed 
38335 +        * check_local tell you if the phys file is stat()ed
38336          * or not. FastCGI doesn't care if the service is
38337          * remote. If the web-server side doesn't contain
38338          * the fastcgi-files we should not stat() for them
38339 @@ -218,11 +220,11 @@
38340  
38341         /*
38342          * append PATH_INFO to SCRIPT_FILENAME
38343 -        * 
38344 +        *
38345          * php needs this if cgi.fix_pathinfo is provied
38346 -        * 
38347 +        *
38348          */
38349 -       
38350 +
38351         unsigned short break_scriptfilename_for_php;
38352  
38353         /*
38354 @@ -231,12 +233,12 @@
38355          *
38356          */
38357         unsigned short allow_xsendfile;
38358 -               
38359 +
38360         ssize_t load; /* replace by host->load */
38361  
38362         size_t max_id; /* corresponds most of the time to
38363         num_procs.
38364 -       
38365 +
38366         only if a process is killed max_id waits for the process itself
38367         to die and decrements its afterwards */
38368  
38369 @@ -245,17 +247,17 @@
38370  
38371  /*
38372   * one extension can have multiple hosts assigned
38373 - * one host can spawn additional processes on the same 
38374 + * one host can spawn additional processes on the same
38375   *   socket (if we control it)
38376   *
38377   * ext -> host -> procs
38378   *    1:n     1:n
38379   *
38380 - * if the fastcgi process is remote that whole goes down 
38381 + * if the fastcgi process is remote that whole goes down
38382   * to
38383   *
38384   * ext -> host -> procs
38385 - *    1:n     1:1 
38386 + *    1:n     1:1
38387   *
38388   * in case of PHP and FCGI_CHILDREN we have again a procs
38389   * but we don't control it directly.
38390 @@ -268,7 +270,7 @@
38391         int note_is_sent;
38392  
38393         fcgi_extension_host **hosts;
38394 -       
38395 +
38396         size_t used;
38397         size_t size;
38398  } fcgi_extension;
38399 @@ -282,10 +284,10 @@
38400  
38401  
38402  typedef struct {
38403 -       fcgi_exts *exts; 
38404 +       fcgi_exts *exts;
38405  
38406         array *ext_mapping;
38407 -       
38408 +
38409         int debug;
38410  } plugin_config;
38411  
38412 @@ -297,7 +299,7 @@
38413  
38414  typedef struct {
38415         char **ptr;
38416 -       
38417 +
38418         size_t size;
38419         size_t used;
38420  } char_array;
38421 @@ -306,44 +308,44 @@
38422  typedef struct {
38423         PLUGIN_DATA;
38424         buffer_uint fcgi_request_id;
38425 -       
38426 +
38427         buffer *fcgi_env;
38428 -       
38429 +
38430         buffer *path;
38431 -       buffer *parse_response;
38432  
38433         buffer *statuskey;
38434 -       
38435 +
38436 +       http_resp *resp;
38437 +
38438         plugin_config **config_storage;
38439 -       
38440 +
38441         plugin_config conf; /* this is only used as long as no handler_ctx is setup */
38442  } plugin_data;
38443  
38444  /* connection specific data */
38445 -typedef enum { 
38446 +typedef enum {
38447         FCGI_STATE_UNSET,
38448 -       FCGI_STATE_INIT, 
38449 -       FCGI_STATE_CONNECT_DELAYED, 
38450 -       FCGI_STATE_PREPARE_WRITE, 
38451 -       FCGI_STATE_WRITE, 
38452 -       FCGI_STATE_READ 
38453 +       FCGI_STATE_INIT,
38454 +       FCGI_STATE_CONNECT_DELAYED,
38455 +       FCGI_STATE_PREPARE_WRITE,
38456 +       FCGI_STATE_WRITE,
38457 +       FCGI_STATE_READ
38458  } fcgi_connection_state_t;
38459  
38460  typedef struct {
38461         fcgi_proc *proc;
38462         fcgi_extension_host *host;
38463         fcgi_extension *ext;
38464 -       
38465 +
38466         fcgi_connection_state_t state;
38467         time_t   state_timestamp;
38468 -       
38469 +
38470         int      reconnects; /* number of reconnect attempts */
38471 -       
38472 -       chunkqueue *rb; /* read queue */
38473 +
38474 +       chunkqueue *rb; /* the raw fcgi read-queue */
38475 +       chunkqueue *http_rb; /* the decoded read-queue for http-parsing */
38476         chunkqueue *wb; /* write queue */
38477 -       
38478 -       buffer   *response_header;
38479 -       
38480 +
38481         size_t    request_id;
38482         int       fd;        /* fd to the fastcgi process */
38483         int       fde_ndx;   /* index into the fd-event buffer */
38484 @@ -352,9 +354,9 @@
38485         int       got_proc;
38486  
38487         int       send_content_body;
38488 -       
38489 +
38490         plugin_config conf;
38491 -       
38492 +
38493         connection *remote_conn;  /* dumb pointer */
38494         plugin_data *plugin_data; /* dumb pointer */
38495  } handler_ctx;
38496 @@ -380,7 +382,7 @@
38497         return di;
38498  }
38499  
38500 -/* dummies of the statistic framework functions 
38501 +/* dummies of the statistic framework functions
38502   * they will be moved to a statistics.c later */
38503  int status_counter_inc(server *srv, const char *s, size_t len) {
38504         data_integer *di = status_counter_get_counter(srv, s, len);
38505 @@ -429,7 +431,7 @@
38506         CLEAN(".connected");
38507         CLEAN(".load");
38508  
38509 -#undef CLEAN   
38510 +#undef CLEAN
38511  
38512  #define CLEAN(x) \
38513         fastcgi_status_copy_procname(b, host, NULL); \
38514 @@ -438,33 +440,32 @@
38515  
38516         CLEAN(".load");
38517  
38518 -#undef CLEAN   
38519 +#undef CLEAN
38520  
38521         return 0;
38522  }
38523  
38524  static handler_ctx * handler_ctx_init() {
38525         handler_ctx * hctx;
38526 -       
38527 +
38528         hctx = calloc(1, sizeof(*hctx));
38529         assert(hctx);
38530 -       
38531 +
38532         hctx->fde_ndx = -1;
38533 -       
38534 -       hctx->response_header = buffer_init();
38535 -       
38536 +
38537         hctx->request_id = 0;
38538         hctx->state = FCGI_STATE_INIT;
38539         hctx->proc = NULL;
38540 -       
38541 +
38542         hctx->fd = -1;
38543 -       
38544 +
38545         hctx->reconnects = 0;
38546         hctx->send_content_body = 1;
38547  
38548         hctx->rb = chunkqueue_init();
38549 +       hctx->http_rb = chunkqueue_init();
38550         hctx->wb = chunkqueue_init();
38551 -       
38552 +
38553         return hctx;
38554  }
38555  
38556 @@ -473,10 +474,9 @@
38557                 hctx->host->load--;
38558                 hctx->host = NULL;
38559         }
38560 -       
38561 -       buffer_free(hctx->response_header);
38562  
38563         chunkqueue_free(hctx->rb);
38564 +       chunkqueue_free(hctx->http_rb);
38565         chunkqueue_free(hctx->wb);
38566  
38567         free(hctx);
38568 @@ -488,21 +488,21 @@
38569         f = calloc(1, sizeof(*f));
38570         f->unixsocket = buffer_init();
38571         f->connection_name = buffer_init();
38572 -       
38573 +
38574         f->prev = NULL;
38575         f->next = NULL;
38576 -       
38577 +
38578         return f;
38579  }
38580  
38581  void fastcgi_process_free(fcgi_proc *f) {
38582         if (!f) return;
38583 -       
38584 +
38585         fastcgi_process_free(f->next);
38586 -       
38587 +
38588         buffer_free(f->unixsocket);
38589         buffer_free(f->connection_name);
38590 -       
38591 +
38592         free(f);
38593  }
38594  
38595 @@ -519,13 +519,13 @@
38596         f->bin_env = array_init();
38597         f->bin_env_copy = array_init();
38598         f->strip_request_uri = buffer_init();
38599 -       
38600 +
38601         return f;
38602  }
38603  
38604  void fastcgi_host_free(fcgi_extension_host *h) {
38605         if (!h) return;
38606 -       
38607 +
38608         buffer_free(h->id);
38609         buffer_free(h->host);
38610         buffer_free(h->unixsocket);
38611 @@ -534,49 +534,49 @@
38612         buffer_free(h->strip_request_uri);
38613         array_free(h->bin_env);
38614         array_free(h->bin_env_copy);
38615 -       
38616 +
38617         fastcgi_process_free(h->first);
38618         fastcgi_process_free(h->unused_procs);
38619 -       
38620 +
38621         free(h);
38622 -       
38623 +
38624  }
38625  
38626  fcgi_exts *fastcgi_extensions_init() {
38627         fcgi_exts *f;
38628  
38629         f = calloc(1, sizeof(*f));
38630 -       
38631 +
38632         return f;
38633  }
38634  
38635  void fastcgi_extensions_free(fcgi_exts *f) {
38636         size_t i;
38637 -       
38638 +
38639         if (!f) return;
38640 -       
38641 +
38642         for (i = 0; i < f->used; i++) {
38643                 fcgi_extension *fe;
38644                 size_t j;
38645 -               
38646 +
38647                 fe = f->exts[i];
38648 -               
38649 +
38650                 for (j = 0; j < fe->used; j++) {
38651                         fcgi_extension_host *h;
38652 -                       
38653 +
38654                         h = fe->hosts[j];
38655 -                       
38656 +
38657                         fastcgi_host_free(h);
38658                 }
38659 -               
38660 +
38661                 buffer_free(fe->key);
38662                 free(fe->hosts);
38663 -               
38664 +
38665                 free(fe);
38666         }
38667 -       
38668 +
38669         free(f->exts);
38670 -       
38671 +
38672         free(f);
38673  }
38674  
38675 @@ -625,24 +625,25 @@
38676                 assert(fe->hosts);
38677         }
38678  
38679 -       fe->hosts[fe->used++] = fh; 
38680 +       fe->hosts[fe->used++] = fh;
38681  
38682         return 0;
38683 -       
38684 +
38685  }
38686  
38687  INIT_FUNC(mod_fastcgi_init) {
38688         plugin_data *p;
38689 -       
38690 +
38691         p = calloc(1, sizeof(*p));
38692 -       
38693 +
38694         p->fcgi_env = buffer_init();
38695 -       
38696 +
38697         p->path = buffer_init();
38698 -       p->parse_response = buffer_init();
38699  
38700 +       p->resp = http_response_init();
38701 +
38702         p->statuskey = buffer_init();
38703 -       
38704 +
38705         return p;
38706  }
38707  
38708 @@ -650,81 +651,82 @@
38709  FREE_FUNC(mod_fastcgi_free) {
38710         plugin_data *p = p_d;
38711         buffer_uint *r = &(p->fcgi_request_id);
38712 -       
38713 +
38714         UNUSED(srv);
38715  
38716         if (r->ptr) free(r->ptr);
38717 -       
38718 +
38719         buffer_free(p->fcgi_env);
38720         buffer_free(p->path);
38721 -       buffer_free(p->parse_response);
38722         buffer_free(p->statuskey);
38723 -       
38724 +
38725 +       http_response_free(p->resp);
38726 +
38727         if (p->config_storage) {
38728                 size_t i, j, n;
38729                 for (i = 0; i < srv->config_context->used; i++) {
38730                         plugin_config *s = p->config_storage[i];
38731                         fcgi_exts *exts;
38732 -                       
38733 +
38734                         if (!s) continue;
38735 -                       
38736 +
38737                         exts = s->exts;
38738  
38739                         for (j = 0; j < exts->used; j++) {
38740                                 fcgi_extension *ex;
38741 -                               
38742 +
38743                                 ex = exts->exts[j];
38744 -                               
38745 +
38746                                 for (n = 0; n < ex->used; n++) {
38747                                         fcgi_proc *proc;
38748                                         fcgi_extension_host *host;
38749 -                                       
38750 +
38751                                         host = ex->hosts[n];
38752 -                                       
38753 +
38754                                         for (proc = host->first; proc; proc = proc->next) {
38755                                                 if (proc->pid != 0) kill(proc->pid, SIGTERM);
38756 -                                               
38757 -                                               if (proc->is_local && 
38758 +
38759 +                                               if (proc->is_local &&
38760                                                     !buffer_is_empty(proc->unixsocket)) {
38761                                                         unlink(proc->unixsocket->ptr);
38762                                                 }
38763                                         }
38764 -                                       
38765 +
38766                                         for (proc = host->unused_procs; proc; proc = proc->next) {
38767                                                 if (proc->pid != 0) kill(proc->pid, SIGTERM);
38768 -                                               
38769 -                                               if (proc->is_local && 
38770 +
38771 +                                               if (proc->is_local &&
38772                                                     !buffer_is_empty(proc->unixsocket)) {
38773                                                         unlink(proc->unixsocket->ptr);
38774                                                 }
38775                                         }
38776                                 }
38777                         }
38778 -                       
38779 +
38780                         fastcgi_extensions_free(s->exts);
38781                         array_free(s->ext_mapping);
38782 -                       
38783 +
38784                         free(s);
38785                 }
38786                 free(p->config_storage);
38787         }
38788 -       
38789 +
38790         free(p);
38791 -       
38792 +
38793         return HANDLER_GO_ON;
38794  }
38795  
38796  static int env_add(char_array *env, const char *key, size_t key_len, const char *val, size_t val_len) {
38797         char *dst;
38798 -       
38799 +
38800         if (!key || !val) return -1;
38801 -       
38802 +
38803         dst = malloc(key_len + val_len + 3);
38804         memcpy(dst, key, key_len);
38805         dst[key_len] = '=';
38806         /* add the \0 from the value */
38807         memcpy(dst + key_len + 1, val, val_len + 1);
38808 -       
38809 +
38810         if (env->size == 0) {
38811                 env->size = 16;
38812                 env->ptr = malloc(env->size * sizeof(*env->ptr));
38813 @@ -732,9 +734,9 @@
38814                 env->size += 16;
38815                 env->ptr = realloc(env->ptr, env->size * sizeof(*env->ptr));
38816         }
38817 -       
38818 +
38819         env->ptr[env->used++] = dst;
38820 -       
38821 +
38822         return 0;
38823  }
38824  
38825 @@ -753,15 +755,15 @@
38826                         if (env->size == 0) {
38827                                 env->size = 16;
38828                                 env->ptr = malloc(env->size * sizeof(*env->ptr));
38829 -                       } else if (env->size == env->used) { 
38830 +                       } else if (env->size == env->used) {
38831                                 env->size += 16;
38832                                 env->ptr = realloc(env->ptr, env->size * sizeof(*env->ptr));
38833                         }
38834 -                       
38835 +
38836                         b->ptr[i] = '\0';
38837  
38838                         env->ptr[env->used++] = start;
38839 -                       
38840 +
38841                         start = b->ptr + i + 1;
38842                         break;
38843                 default:
38844 @@ -794,7 +796,7 @@
38845         return 0;
38846  }
38847  
38848 -static int fcgi_spawn_connection(server *srv, 
38849 +static int fcgi_spawn_connection(server *srv,
38850                                  plugin_data *p,
38851                                  fcgi_extension_host *host,
38852                                  fcgi_proc *proc) {
38853 @@ -806,31 +808,27 @@
38854  #endif
38855         struct sockaddr_in fcgi_addr_in;
38856         struct sockaddr *fcgi_addr;
38857 -       
38858 +
38859         socklen_t servlen;
38860 -       
38861 +
38862  #ifndef HAVE_FORK
38863         return -1;
38864  #endif
38865 -       
38866 +
38867         if (p->conf.debug) {
38868                 log_error_write(srv, __FILE__, __LINE__, "sdb",
38869                                 "new proc, socket:", proc->port, proc->unixsocket);
38870         }
38871 -               
38872 +
38873         if (!buffer_is_empty(proc->unixsocket)) {
38874                 memset(&fcgi_addr, 0, sizeof(fcgi_addr));
38875 -               
38876 +
38877  #ifdef HAVE_SYS_UN_H
38878                 fcgi_addr_un.sun_family = AF_UNIX;
38879                 strcpy(fcgi_addr_un.sun_path, proc->unixsocket->ptr);
38880 -               
38881 -#ifdef SUN_LEN
38882 +
38883                 servlen = SUN_LEN(&fcgi_addr_un);
38884 -#else
38885 -               /* stevens says: */
38886 -               servlen = proc->unixsocket->used + sizeof(fcgi_addr_un.sun_family);
38887 -#endif
38888 +
38889                 socket_type = AF_UNIX;
38890                 fcgi_addr = (struct sockaddr *) &fcgi_addr_un;
38891  
38892 @@ -844,108 +842,108 @@
38893  #endif
38894         } else {
38895                 fcgi_addr_in.sin_family = AF_INET;
38896 -               
38897 +
38898                 if (buffer_is_empty(host->host)) {
38899                         fcgi_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
38900                 } else {
38901                         struct hostent *he;
38902 -                       
38903 +
38904                         /* set a usefull default */
38905                         fcgi_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
38906 -                       
38907 -                       
38908 +
38909 +
38910                         if (NULL == (he = gethostbyname(host->host->ptr))) {
38911 -                               log_error_write(srv, __FILE__, __LINE__, 
38912 -                                               "sdb", "gethostbyname failed: ", 
38913 +                               log_error_write(srv, __FILE__, __LINE__,
38914 +                                               "sdb", "gethostbyname failed: ",
38915                                                 h_errno, host->host);
38916                                 return -1;
38917                         }
38918 -                       
38919 +
38920                         if (he->h_addrtype != AF_INET) {
38921                                 log_error_write(srv, __FILE__, __LINE__, "sd", "addr-type != AF_INET: ", he->h_addrtype);
38922                                 return -1;
38923                         }
38924 -                       
38925 +
38926                         if (he->h_length != sizeof(struct in_addr)) {
38927                                 log_error_write(srv, __FILE__, __LINE__, "sd", "addr-length != sizeof(in_addr): ", he->h_length);
38928                                 return -1;
38929                         }
38930 -                       
38931 +
38932                         memcpy(&(fcgi_addr_in.sin_addr.s_addr), he->h_addr_list[0], he->h_length);
38933 -                       
38934 +
38935                 }
38936                 fcgi_addr_in.sin_port = htons(proc->port);
38937                 servlen = sizeof(fcgi_addr_in);
38938 -               
38939 +
38940                 socket_type = AF_INET;
38941                 fcgi_addr = (struct sockaddr *) &fcgi_addr_in;
38942 -               
38943 +
38944                 buffer_copy_string(proc->connection_name, "tcp:");
38945                 buffer_append_string_buffer(proc->connection_name, host->host);
38946                 buffer_append_string(proc->connection_name, ":");
38947                 buffer_append_long(proc->connection_name, proc->port);
38948         }
38949 -       
38950 +
38951         if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
38952 -               log_error_write(srv, __FILE__, __LINE__, "ss", 
38953 +               log_error_write(srv, __FILE__, __LINE__, "ss",
38954                                 "failed:", strerror(errno));
38955                 return -1;
38956         }
38957 -       
38958 +
38959         if (-1 == connect(fcgi_fd, fcgi_addr, servlen)) {
38960                 /* server is not up, spawn in  */
38961                 pid_t child;
38962                 int val;
38963 -               
38964 -               if (errno != ENOENT && 
38965 +
38966 +               if (errno != ENOENT &&
38967                     !buffer_is_empty(proc->unixsocket)) {
38968                         unlink(proc->unixsocket->ptr);
38969                 }
38970 -               
38971 +
38972                 close(fcgi_fd);
38973 -               
38974 +
38975                 /* reopen socket */
38976                 if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
38977 -                       log_error_write(srv, __FILE__, __LINE__, "ss", 
38978 +                       log_error_write(srv, __FILE__, __LINE__, "ss",
38979                                 "socket failed:", strerror(errno));
38980                         return -1;
38981                 }
38982 -               
38983 +
38984                 val = 1;
38985                 if (setsockopt(fcgi_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
38986 -                       log_error_write(srv, __FILE__, __LINE__, "ss", 
38987 +                       log_error_write(srv, __FILE__, __LINE__, "ss",
38988                                         "socketsockopt failed:", strerror(errno));
38989                         return -1;
38990                 }
38991 -               
38992 +
38993                 /* create socket */
38994                 if (-1 == bind(fcgi_fd, fcgi_addr, servlen)) {
38995 -                       log_error_write(srv, __FILE__, __LINE__, "sbs", 
38996 -                               "bind failed for:", 
38997 +                       log_error_write(srv, __FILE__, __LINE__, "sbs",
38998 +                               "bind failed for:",
38999                                 proc->connection_name,
39000                                 strerror(errno));
39001                         return -1;
39002                 }
39003 -               
39004 +
39005                 if (-1 == listen(fcgi_fd, 1024)) {
39006 -                       log_error_write(srv, __FILE__, __LINE__, "ss", 
39007 +                       log_error_write(srv, __FILE__, __LINE__, "ss",
39008                                 "listen failed:", strerror(errno));
39009                         return -1;
39010                 }
39011 -               
39012 -#ifdef HAVE_FORK       
39013 +
39014 +#ifndef _WIN32
39015                 switch ((child = fork())) {
39016                 case 0: {
39017                         size_t i = 0;
39018                         char *c;
39019                         char_array env;
39020                         char_array arg;
39021 -                       
39022 +
39023                         /* create environment */
39024                         env.ptr = NULL;
39025                         env.size = 0;
39026                         env.used = 0;
39027 -                       
39028 +
39029                         arg.ptr = NULL;
39030                         arg.size = 0;
39031                         arg.used = 0;
39032 @@ -955,18 +953,18 @@
39033                                 dup2(fcgi_fd, FCGI_LISTENSOCK_FILENO);
39034                                 close(fcgi_fd);
39035                         }
39036 -                       
39037 +
39038                         /* we don't need the client socket */
39039                         for (i = 3; i < 256; i++) {
39040                                 close(i);
39041                         }
39042 -                       
39043 +
39044                         /* build clean environment */
39045                         if (host->bin_env_copy->used) {
39046                                 for (i = 0; i < host->bin_env_copy->used; i++) {
39047                                         data_string *ds = (data_string *)host->bin_env_copy->data[i];
39048                                         char *ge;
39049 -                                       
39050 +
39051                                         if (NULL != (ge = getenv(ds->value->ptr))) {
39052                                                 env_add(&env, CONST_BUF_LEN(ds->value), ge, strlen(ge));
39053                                         }
39054 @@ -974,39 +972,39 @@
39055                         } else {
39056                                 for (i = 0; environ[i]; i++) {
39057                                         char *eq;
39058 -                                       
39059 +
39060                                         if (NULL != (eq = strchr(environ[i], '='))) {
39061                                                 env_add(&env, environ[i], eq - environ[i], eq+1, strlen(eq+1));
39062                                         }
39063                                 }
39064                         }
39065 -                       
39066 +
39067                         /* create environment */
39068                         for (i = 0; i < host->bin_env->used; i++) {
39069                                 data_string *ds = (data_string *)host->bin_env->data[i];
39070 -                               
39071 +
39072                                 env_add(&env, CONST_BUF_LEN(ds->key), CONST_BUF_LEN(ds->value));
39073                         }
39074 -                       
39075 +
39076                         for (i = 0; i < env.used; i++) {
39077                                 /* search for PHP_FCGI_CHILDREN */
39078                                 if (0 == strncmp(env.ptr[i], "PHP_FCGI_CHILDREN=", sizeof("PHP_FCGI_CHILDREN=") - 1)) break;
39079                         }
39080 -                       
39081 +
39082                         /* not found, add a default */
39083                         if (i == env.used) {
39084                                 env_add(&env, CONST_STR_LEN("PHP_FCGI_CHILDREN"), CONST_STR_LEN("1"));
39085                         }
39086 -                       
39087 +
39088                         env.ptr[env.used] = NULL;
39089  
39090                         parse_binpath(&arg, host->bin_path);
39091 -                       
39092 +
39093                         /* chdir into the base of the bin-path,
39094                          * search for the last / */
39095                         if (NULL != (c = strrchr(arg.ptr[0], '/'))) {
39096                                 *c = '\0';
39097 -                       
39098 +
39099                                 /* change to the physical directory */
39100                                 if (-1 == chdir(arg.ptr[0])) {
39101                                         *c = '/';
39102 @@ -1018,12 +1016,12 @@
39103  
39104                         /* exec the cgi */
39105                         execve(arg.ptr[0], arg.ptr, env.ptr);
39106 -                       
39107 -                       log_error_write(srv, __FILE__, __LINE__, "sbs", 
39108 +
39109 +                       log_error_write(srv, __FILE__, __LINE__, "sbs",
39110                                         "execve failed for:", host->bin_path, strerror(errno));
39111 -                       
39112 +
39113                         exit(errno);
39114 -                       
39115 +
39116                         break;
39117                 }
39118                 case -1:
39119 @@ -1031,17 +1029,17 @@
39120                         break;
39121                 default:
39122                         /* father */
39123 -                       
39124 +
39125                         /* wait */
39126                         select(0, NULL, NULL, NULL, &tv);
39127 -                       
39128 +
39129                         switch (waitpid(child, &status, WNOHANG)) {
39130                         case 0:
39131                                 /* child still running after timeout, good */
39132                                 break;
39133                         case -1:
39134                                 /* no PID found ? should never happen */
39135 -                               log_error_write(srv, __FILE__, __LINE__, "ss", 
39136 +                               log_error_write(srv, __FILE__, __LINE__, "ss",
39137                                                 "pid not found:", strerror(errno));
39138                                 return -1;
39139                         default:
39140 @@ -1049,10 +1047,10 @@
39141                                                 "the fastcgi-backend", host->bin_path, "failed to start:");
39142                                 /* the child should not terminate at all */
39143                                 if (WIFEXITED(status)) {
39144 -                                       log_error_write(srv, __FILE__, __LINE__, "sdb", 
39145 -                                                       "child exited with status", 
39146 +                                       log_error_write(srv, __FILE__, __LINE__, "sdb",
39147 +                                                       "child exited with status",
39148                                                         WEXITSTATUS(status), host->bin_path);
39149 -                                       log_error_write(srv, __FILE__, __LINE__, "s", 
39150 +                                       log_error_write(srv, __FILE__, __LINE__, "s",
39151                                                         "if you try do run PHP as FastCGI backend make sure you use the FastCGI enabled version.\n"
39152                                                         "You can find out if it is the right one by executing 'php -v' and it should display '(cgi-fcgi)' "
39153                                                         "in the output, NOT (cgi) NOR (cli)\n"
39154 @@ -1060,8 +1058,8 @@
39155                                         log_error_write(srv, __FILE__, __LINE__, "s",
39156                                                         "If this is PHP on Gentoo add fastcgi to the USE flags");
39157                                 } else if (WIFSIGNALED(status)) {
39158 -                                       log_error_write(srv, __FILE__, __LINE__, "sd", 
39159 -                                                       "terminated by signal:", 
39160 +                                       log_error_write(srv, __FILE__, __LINE__, "sd",
39161 +                                                       "terminated by signal:",
39162                                                         WTERMSIG(status));
39163  
39164                                         if (WTERMSIG(status) == 11) {
39165 @@ -1071,8 +1069,8 @@
39166                                                                 "If this is PHP try to remove the byte-code caches for now and try again.");
39167                                         }
39168                                 } else {
39169 -                                       log_error_write(srv, __FILE__, __LINE__, "sd", 
39170 -                                                       "child died somehow:", 
39171 +                                       log_error_write(srv, __FILE__, __LINE__, "sd",
39172 +                                                       "child died somehow:",
39173                                                         status);
39174                                 }
39175                                 return -1;
39176 @@ -1082,26 +1080,26 @@
39177                         proc->pid = child;
39178                         proc->last_used = srv->cur_ts;
39179                         proc->is_local = 1;
39180 -                                               
39181 +
39182                         break;
39183                 }
39184  #endif
39185         } else {
39186                 proc->is_local = 0;
39187                 proc->pid = 0;
39188 -               
39189 +
39190                 if (p->conf.debug) {
39191                         log_error_write(srv, __FILE__, __LINE__, "sb",
39192                                         "(debug) socket is already used, won't spawn:",
39193                                         proc->connection_name);
39194                 }
39195         }
39196 -       
39197 +
39198         proc->state = PROC_STATE_RUNNING;
39199         host->active_procs++;
39200 -       
39201 +
39202         close(fcgi_fd);
39203 -       
39204 +
39205         return 0;
39206  }
39207  
39208 @@ -1111,93 +1109,93 @@
39209         data_unset *du;
39210         size_t i = 0;
39211         buffer *fcgi_mode = buffer_init();
39212 -       
39213 -       config_values_t cv[] = { 
39214 +
39215 +       config_values_t cv[] = {
39216                 { "fastcgi.server",              NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
39217                 { "fastcgi.debug",               NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
39218                 { "fastcgi.map-extensions",      NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 2 */
39219                 { NULL,                          NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
39220         };
39221 -       
39222 +
39223         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
39224 -       
39225 +
39226         for (i = 0; i < srv->config_context->used; i++) {
39227                 plugin_config *s;
39228                 array *ca;
39229 -               
39230 +
39231                 s = malloc(sizeof(plugin_config));
39232                 s->exts          = fastcgi_extensions_init();
39233                 s->debug         = 0;
39234                 s->ext_mapping   = array_init();
39235 -               
39236 +
39237                 cv[0].destination = s->exts;
39238                 cv[1].destination = &(s->debug);
39239                 cv[2].destination = s->ext_mapping;
39240 -               
39241 +
39242                 p->config_storage[i] = s;
39243                 ca = ((data_config *)srv->config_context->data[i])->value;
39244 -       
39245 +
39246                 if (0 != config_insert_values_global(srv, ca, cv)) {
39247                         return HANDLER_ERROR;
39248                 }
39249 -               
39250 -               /* 
39251 +
39252 +               /*
39253                  * <key> = ( ... )
39254                  */
39255 -               
39256 +
39257                 if (NULL != (du = array_get_element(ca, "fastcgi.server"))) {
39258                         size_t j;
39259                         data_array *da = (data_array *)du;
39260 -                       
39261 +
39262                         if (du->type != TYPE_ARRAY) {
39263 -                               log_error_write(srv, __FILE__, __LINE__, "sss", 
39264 +                               log_error_write(srv, __FILE__, __LINE__, "sss",
39265                                                 "unexpected type for key: ", "fastcgi.server", "array of strings");
39266 -                               
39267 +
39268                                 return HANDLER_ERROR;
39269                         }
39270 -                       
39271 -                       
39272 -                       /* 
39273 -                        * fastcgi.server = ( "<ext>" => ( ... ), 
39274 +
39275 +
39276 +                       /*
39277 +                        * fastcgi.server = ( "<ext>" => ( ... ),
39278                          *                    "<ext>" => ( ... ) )
39279                          */
39280 -                       
39281 +
39282                         for (j = 0; j < da->value->used; j++) {
39283                                 size_t n;
39284                                 data_array *da_ext = (data_array *)da->value->data[j];
39285 -                               
39286 +
39287                                 if (da->value->data[j]->type != TYPE_ARRAY) {
39288 -                                       log_error_write(srv, __FILE__, __LINE__, "sssbs", 
39289 -                                                       "unexpected type for key: ", "fastcgi.server", 
39290 +                                       log_error_write(srv, __FILE__, __LINE__, "sssbs",
39291 +                                                       "unexpected type for key: ", "fastcgi.server",
39292                                                         "[", da->value->data[j]->key, "](string)");
39293 -                                       
39294 +
39295                                         return HANDLER_ERROR;
39296                                 }
39297 -                               
39298 -                               /* 
39299 -                                * da_ext->key == name of the extension 
39300 +
39301 +                               /*
39302 +                                * da_ext->key == name of the extension
39303                                  */
39304 -                               
39305 -                               /* 
39306 -                                * fastcgi.server = ( "<ext>" => 
39307 -                                *                     ( "<host>" => ( ... ), 
39308 +
39309 +                               /*
39310 +                                * fastcgi.server = ( "<ext>" =>
39311 +                                *                     ( "<host>" => ( ... ),
39312                                  *                       "<host>" => ( ... )
39313 -                                *                     ), 
39314 +                                *                     ),
39315                                  *                    "<ext>" => ... )
39316                                  */
39317 -                                       
39318 +
39319                                 for (n = 0; n < da_ext->value->used; n++) {
39320                                         data_array *da_host = (data_array *)da_ext->value->data[n];
39321 -                                       
39322 +
39323                                         fcgi_extension_host *host;
39324 -                                       
39325 -                                       config_values_t fcv[] = { 
39326 +
39327 +                                       config_values_t fcv[] = {
39328                                                 { "host",              NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
39329                                                 { "docroot",           NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 1 */
39330                                                 { "mode",              NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 2 */
39331                                                 { "socket",            NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 3 */
39332                                                 { "bin-path",          NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 4 */
39333 -                                               
39334 +
39335                                                 { "check-local",       NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },      /* 5 */
39336                                                 { "port",              NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 6 */
39337                                                 { "min-procs-not-working",         NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 7 this is broken for now */
39338 @@ -1205,28 +1203,28 @@
39339                                                 { "max-load-per-proc", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 9 */
39340                                                 { "idle-timeout",      NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 10 */
39341                                                 { "disable-time",      NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 11 */
39342 -                                               
39343 +
39344                                                 { "bin-environment",   NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },        /* 12 */
39345                                                 { "bin-copy-environment", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },     /* 13 */
39346 -                                               
39347 +
39348                                                 { "broken-scriptfilename", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },  /* 14 */
39349                                                 { "allow-x-send-file", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },      /* 15 */
39350                                                 { "strip-request-uri",  NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },      /* 16 */
39351 -                                               
39352 +
39353                                                 { NULL,                NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
39354                                         };
39355 -                                       
39356 +
39357                                         if (da_host->type != TYPE_ARRAY) {
39358 -                                               log_error_write(srv, __FILE__, __LINE__, "ssSBS", 
39359 -                                                               "unexpected type for key:", 
39360 -                                                               "fastcgi.server", 
39361 +                                               log_error_write(srv, __FILE__, __LINE__, "ssSBS",
39362 +                                                               "unexpected type for key:",
39363 +                                                               "fastcgi.server",
39364                                                                 "[", da_host->key, "](string)");
39365 -                                               
39366 +
39367                                                 return HANDLER_ERROR;
39368                                         }
39369 -                                       
39370 +
39371                                         host = fastcgi_host_init();
39372 -                                       
39373 +
39374                                         buffer_copy_string_buffer(host->id, da_host->key);
39375  
39376                                         host->check_local  = 1;
39377 @@ -1238,13 +1236,13 @@
39378                                         host->disable_time = 60;
39379                                         host->break_scriptfilename_for_php = 0;
39380                                         host->allow_xsendfile = 0; /* handle X-LIGHTTPD-send-file */
39381 -                                       
39382 +
39383                                         fcv[0].destination = host->host;
39384                                         fcv[1].destination = host->docroot;
39385                                         fcv[2].destination = fcgi_mode;
39386                                         fcv[3].destination = host->unixsocket;
39387                                         fcv[4].destination = host->bin_path;
39388 -                                       
39389 +
39390                                         fcv[5].destination = &(host->check_local);
39391                                         fcv[6].destination = &(host->port);
39392                                         fcv[7].destination = &(host->min_procs);
39393 @@ -1252,35 +1250,35 @@
39394                                         fcv[9].destination = &(host->max_load_per_proc);
39395                                         fcv[10].destination = &(host->idle_timeout);
39396                                         fcv[11].destination = &(host->disable_time);
39397 -                                       
39398 +
39399                                         fcv[12].destination = host->bin_env;
39400                                         fcv[13].destination = host->bin_env_copy;
39401                                         fcv[14].destination = &(host->break_scriptfilename_for_php);
39402                                         fcv[15].destination = &(host->allow_xsendfile);
39403                                         fcv[16].destination = host->strip_request_uri;
39404 -                                       
39405 +
39406                                         if (0 != config_insert_values_internal(srv, da_host->value, fcv)) {
39407                                                 return HANDLER_ERROR;
39408                                         }
39409 -                                                       
39410 -                                       if ((!buffer_is_empty(host->host) || host->port) && 
39411 +
39412 +                                       if ((!buffer_is_empty(host->host) || host->port) &&
39413                                             !buffer_is_empty(host->unixsocket)) {
39414 -                                               log_error_write(srv, __FILE__, __LINE__, "sbsbsbs", 
39415 +                                               log_error_write(srv, __FILE__, __LINE__, "sbsbsbs",
39416                                                                 "either host/port or socket have to be set in:",
39417 -                                                               da->key, "= (", 
39418 +                                                               da->key, "= (",
39419                                                                 da_ext->key, " => (",
39420                                                                 da_host->key, " ( ...");
39421  
39422                                                 return HANDLER_ERROR;
39423                                         }
39424 -                                       
39425 +
39426                                         if (!buffer_is_empty(host->unixsocket)) {
39427                                                 /* unix domain socket */
39428 -                                               
39429 +
39430                                                 if (host->unixsocket->used > UNIX_PATH_MAX - 2) {
39431 -                                                       log_error_write(srv, __FILE__, __LINE__, "sbsbsbs", 
39432 +                                                       log_error_write(srv, __FILE__, __LINE__, "sbsbsbs",
39433                                                                         "unixsocket is too long in:",
39434 -                                                                       da->key, "= (", 
39435 +                                                                       da->key, "= (",
39436                                                                         da_ext->key, " => (",
39437                                                                         da_host->key, " ( ...");
39438  
39439 @@ -1288,37 +1286,37 @@
39440                                                 }
39441                                         } else {
39442                                                 /* tcp/ip */
39443 -                                               
39444 -                                               if (buffer_is_empty(host->host) && 
39445 +
39446 +                                               if (buffer_is_empty(host->host) &&
39447                                                     buffer_is_empty(host->bin_path)) {
39448 -                                                       log_error_write(srv, __FILE__, __LINE__, "sbsbsbs", 
39449 +                                                       log_error_write(srv, __FILE__, __LINE__, "sbsbsbs",
39450                                                                         "host or binpath have to be set in:",
39451 -                                                                       da->key, "= (", 
39452 +                                                                       da->key, "= (",
39453                                                                         da_ext->key, " => (",
39454                                                                         da_host->key, " ( ...");
39455 -                                                       
39456 +
39457                                                         return HANDLER_ERROR;
39458                                                 } else if (host->port == 0) {
39459 -                                                       log_error_write(srv, __FILE__, __LINE__, "sbsbsbs", 
39460 +                                                       log_error_write(srv, __FILE__, __LINE__, "sbsbsbs",
39461                                                                         "port has to be set in:",
39462 -                                                                       da->key, "= (", 
39463 +                                                                       da->key, "= (",
39464                                                                         da_ext->key, " => (",
39465                                                                         da_host->key, " ( ...");
39466  
39467                                                         return HANDLER_ERROR;
39468                                                 }
39469                                         }
39470 -                                               
39471 -                                       if (!buffer_is_empty(host->bin_path)) { 
39472 +
39473 +                                       if (!buffer_is_empty(host->bin_path)) {
39474                                                 /* a local socket + self spawning */
39475                                                 size_t pno;
39476  
39477                                                 /* HACK:  just to make sure the adaptive spawing is disabled */
39478                                                 host->min_procs = host->max_procs;
39479 -                                               
39480 +
39481                                                 if (host->min_procs > host->max_procs) host->max_procs = host->min_procs;
39482                                                 if (host->max_load_per_proc < 1) host->max_load_per_proc = 0;
39483 -                                               
39484 +
39485                                                 if (s->debug) {
39486                                                         log_error_write(srv, __FILE__, __LINE__, "ssbsdsbsdsd",
39487                                                                         "--- fastcgi spawning local",
39488 @@ -1328,7 +1326,7 @@
39489                                                                         "\n\tmin-procs:", host->min_procs,
39490                                                                         "\n\tmax-procs:", host->max_procs);
39491                                                 }
39492 -                                               
39493 +
39494                                                 for (pno = 0; pno < host->min_procs; pno++) {
39495                                                         fcgi_proc *proc;
39496  
39497 @@ -1343,7 +1341,7 @@
39498                                                                 buffer_append_string(proc->unixsocket, "-");
39499                                                                 buffer_append_long(proc->unixsocket, pno);
39500                                                         }
39501 -                                                       
39502 +
39503                                                         if (s->debug) {
39504                                                                 log_error_write(srv, __FILE__, __LINE__, "ssdsbsdsd",
39505                                                                                 "--- fastcgi spawning",
39506 @@ -1351,7 +1349,7 @@
39507                                                                                 "\n\tsocket", host->unixsocket,
39508                                                                                 "\n\tcurrent:", pno, "/", host->min_procs);
39509                                                         }
39510 -                                                       
39511 +
39512                                                         if (fcgi_spawn_connection(srv, p, host, proc)) {
39513                                                                 log_error_write(srv, __FILE__, __LINE__, "s",
39514                                                                                 "[ERROR]: spawning fcgi failed.");
39515 @@ -1359,35 +1357,35 @@
39516                                                         }
39517  
39518                                                         fastcgi_status_init(srv, p->statuskey, host, proc);
39519 -                                                       
39520 +
39521                                                         proc->next = host->first;
39522                                                         if (host->first)        host->first->prev = proc;
39523 -                                                       
39524 +
39525                                                         host->first = proc;
39526                                                 }
39527                                         } else {
39528                                                 fcgi_proc *proc;
39529 -                                               
39530 +
39531                                                 proc = fastcgi_process_init();
39532                                                 proc->id = host->num_procs++;
39533                                                 host->max_id++;
39534                                                 host->active_procs++;
39535                                                 proc->state = PROC_STATE_RUNNING;
39536 -                                               
39537 +
39538                                                 if (buffer_is_empty(host->unixsocket)) {
39539                                                         proc->port = host->port;
39540                                                 } else {
39541                                                         buffer_copy_string_buffer(proc->unixsocket, host->unixsocket);
39542                                                 }
39543 -                                               
39544 +
39545                                                 fastcgi_status_init(srv, p->statuskey, host, proc);
39546  
39547                                                 host->first = proc;
39548 -                                               
39549 +
39550                                                 host->min_procs = 1;
39551                                                 host->max_procs = 1;
39552                                         }
39553 -                                       
39554 +
39555                                         if (!buffer_is_empty(fcgi_mode)) {
39556                                                 if (strcmp(fcgi_mode->ptr, "responder") == 0) {
39557                                                         host->mode = FCGI_RESPONDER;
39558 @@ -1411,16 +1409,16 @@
39559                         }
39560                 }
39561         }
39562 -       
39563 +
39564         buffer_free(fcgi_mode);
39565 -       
39566 +
39567         return HANDLER_GO_ON;
39568  }
39569  
39570  static int fcgi_set_state(server *srv, handler_ctx *hctx, fcgi_connection_state_t state) {
39571         hctx->state = state;
39572         hctx->state_timestamp = srv->cur_ts;
39573 -       
39574 +
39575         return 0;
39576  }
39577  
39578 @@ -1429,13 +1427,13 @@
39579         size_t m = 0;
39580         size_t i;
39581         buffer_uint *r = &(p->fcgi_request_id);
39582 -       
39583 +
39584         UNUSED(srv);
39585  
39586         for (i = 0; i < r->used; i++) {
39587                 if (r->ptr[i] > m) m = r->ptr[i];
39588         }
39589 -       
39590 +
39591         if (r->size == 0) {
39592                 r->size = 16;
39593                 r->ptr = malloc(sizeof(*r->ptr) * r->size);
39594 @@ -1443,54 +1441,54 @@
39595                 r->size += 16;
39596                 r->ptr = realloc(r->ptr, sizeof(*r->ptr) * r->size);
39597         }
39598 -       
39599 +
39600         r->ptr[r->used++] = ++m;
39601 -       
39602 +
39603         return m;
39604  }
39605  
39606  static int fcgi_requestid_del(server *srv, plugin_data *p, size_t request_id) {
39607         size_t i;
39608         buffer_uint *r = &(p->fcgi_request_id);
39609 -       
39610 +
39611         UNUSED(srv);
39612  
39613         for (i = 0; i < r->used; i++) {
39614                 if (r->ptr[i] == request_id) break;
39615         }
39616 -       
39617 +
39618         if (i != r->used) {
39619                 /* found */
39620 -               
39621 +
39622                 if (i != r->used - 1) {
39623                         r->ptr[i] = r->ptr[r->used - 1];
39624                 }
39625                 r->used--;
39626         }
39627 -       
39628 +
39629         return 0;
39630  }
39631  void fcgi_connection_close(server *srv, handler_ctx *hctx) {
39632         plugin_data *p;
39633         connection  *con;
39634 -       
39635 +
39636         if (NULL == hctx) return;
39637 -       
39638 +
39639         p    = hctx->plugin_data;
39640         con  = hctx->remote_conn;
39641 -       
39642 +
39643         if (con->mode != p->id) {
39644                 WP();
39645                 return;
39646         }
39647 -       
39648 +
39649         if (hctx->fd != -1) {
39650                 fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
39651                 fdevent_unregister(srv->ev, hctx->fd);
39652                 close(hctx->fd);
39653                 srv->cur_fds--;
39654         }
39655 -       
39656 +
39657         if (hctx->request_id != 0) {
39658                 fcgi_requestid_del(srv, p, hctx->request_id);
39659         }
39660 @@ -1499,7 +1497,7 @@
39661                 if (hctx->got_proc) {
39662                         /* after the connect the process gets a load */
39663                         hctx->proc->load--;
39664 -                       
39665 +
39666                         status_counter_dec(srv, CONST_STR_LEN("fastcgi.active-requests"));
39667  
39668                         fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
39669 @@ -1509,39 +1507,39 @@
39670  
39671                         if (p->conf.debug) {
39672                                 log_error_write(srv, __FILE__, __LINE__, "ssdsbsd",
39673 -                                               "released proc:", 
39674 -                                               "pid:", hctx->proc->pid, 
39675 -                                               "socket:", hctx->proc->connection_name, 
39676 +                                               "released proc:",
39677 +                                               "pid:", hctx->proc->pid,
39678 +                                               "socket:", hctx->proc->connection_name,
39679                                                 "load:", hctx->proc->load);
39680                         }
39681                 }
39682         }
39683  
39684 -       
39685 +
39686         handler_ctx_free(hctx);
39687 -       con->plugin_ctx[p->id] = NULL;  
39688 +       con->plugin_ctx[p->id] = NULL;
39689  }
39690  
39691  static int fcgi_reconnect(server *srv, handler_ctx *hctx) {
39692         plugin_data *p    = hctx->plugin_data;
39693 -       
39694 -       /* child died 
39695 -        * 
39696 -        * 1. 
39697 -        * 
39698 +
39699 +       /* child died
39700 +        *
39701 +        * 1.
39702 +        *
39703          * connect was ok, connection was accepted
39704          * but the php accept loop checks after the accept if it should die or not.
39705 -        * 
39706 -        * if yes we can only detect it at a write() 
39707 -        * 
39708 +        *
39709 +        * if yes we can only detect it at a write()
39710 +        *
39711          * next step is resetting this attemp and setup a connection again
39712 -        * 
39713 +        *
39714          * if we have more then 5 reconnects for the same request, die
39715 -        * 
39716 -        * 2. 
39717 -        * 
39718 +        *
39719 +        * 2.
39720 +        *
39721          * we have a connection but the child died by some other reason
39722 -        * 
39723 +        *
39724          */
39725  
39726         if (hctx->fd != -1) {
39727 @@ -1551,59 +1549,59 @@
39728                 srv->cur_fds--;
39729                 hctx->fd = -1;
39730         }
39731 -       
39732 +
39733         fcgi_requestid_del(srv, p, hctx->request_id);
39734 -       
39735 +
39736         fcgi_set_state(srv, hctx, FCGI_STATE_INIT);
39737 -       
39738 +
39739         hctx->request_id = 0;
39740         hctx->reconnects++;
39741 -       
39742 +
39743         if (p->conf.debug > 2) {
39744                 if (hctx->proc) {
39745                         log_error_write(srv, __FILE__, __LINE__, "sdb",
39746 -                                       "release proc for reconnect:", 
39747 +                                       "release proc for reconnect:",
39748                                         hctx->proc->pid, hctx->proc->connection_name);
39749                 } else {
39750                         log_error_write(srv, __FILE__, __LINE__, "sb",
39751 -                                       "release proc for reconnect:", 
39752 +                                       "release proc for reconnect:",
39753                                         hctx->host->unixsocket);
39754                 }
39755         }
39756  
39757 -       if (hctx->proc && hctx->got_proc) {     
39758 +       if (hctx->proc && hctx->got_proc) {
39759                 hctx->proc->load--;
39760         }
39761  
39762         /* perhaps another host gives us more luck */
39763         hctx->host->load--;
39764         hctx->host = NULL;
39765 -       
39766 +
39767         return 0;
39768  }
39769  
39770  
39771  static handler_t fcgi_connection_reset(server *srv, connection *con, void *p_d) {
39772         plugin_data *p = p_d;
39773 -       
39774 +
39775         fcgi_connection_close(srv, con->plugin_ctx[p->id]);
39776 -       
39777 +
39778         return HANDLER_GO_ON;
39779  }
39780  
39781  
39782  static int fcgi_env_add(buffer *env, const char *key, size_t key_len, const char *val, size_t val_len) {
39783         size_t len;
39784 -       
39785 +
39786         if (!key || !val) return -1;
39787 -       
39788 +
39789         len = key_len + val_len;
39790 -       
39791 +
39792         len += key_len > 127 ? 4 : 1;
39793         len += val_len > 127 ? 4 : 1;
39794 -       
39795 +
39796         buffer_prepare_append(env, len);
39797 -       
39798 +
39799         if (key_len > 127) {
39800                 env->ptr[env->used++] = ((key_len >> 24) & 0xff) | 0x80;
39801                 env->ptr[env->used++] = (key_len >> 16) & 0xff;
39802 @@ -1612,7 +1610,7 @@
39803         } else {
39804                 env->ptr[env->used++] = (key_len >> 0) & 0xff;
39805         }
39806 -       
39807 +
39808         if (val_len > 127) {
39809                 env->ptr[env->used++] = ((val_len >> 24) & 0xff) | 0x80;
39810                 env->ptr[env->used++] = (val_len >> 16) & 0xff;
39811 @@ -1621,12 +1619,12 @@
39812         } else {
39813                 env->ptr[env->used++] = (val_len >> 0) & 0xff;
39814         }
39815 -       
39816 +
39817         memcpy(env->ptr + env->used, key, key_len);
39818         env->used += key_len;
39819         memcpy(env->ptr + env->used, val, val_len);
39820         env->used += val_len;
39821 -       
39822 +
39823         return 0;
39824  }
39825  
39826 @@ -1639,11 +1637,11 @@
39827         header->contentLengthB1 = (contentLength >> 8) & 0xff;
39828         header->paddingLength = paddingLength;
39829         header->reserved = 0;
39830 -       
39831 +
39832         return 0;
39833  }
39834  /**
39835 - * 
39836 + *
39837   * returns
39838   *   -1 error
39839   *    0 connected
39840 @@ -1665,26 +1663,23 @@
39841         struct sockaddr_un fcgi_addr_un;
39842  #endif
39843         socklen_t servlen;
39844 -       
39845 +
39846         fcgi_extension_host *host = hctx->host;
39847         fcgi_proc *proc   = hctx->proc;
39848         int fcgi_fd       = hctx->fd;
39849 -       
39850 +
39851         memset(&fcgi_addr, 0, sizeof(fcgi_addr));
39852 -       
39853 +
39854         if (!buffer_is_empty(proc->unixsocket)) {
39855  #ifdef HAVE_SYS_UN_H
39856                 /* use the unix domain socket */
39857                 fcgi_addr_un.sun_family = AF_UNIX;
39858                 strcpy(fcgi_addr_un.sun_path, proc->unixsocket->ptr);
39859 -#ifdef SUN_LEN
39860 +
39861                 servlen = SUN_LEN(&fcgi_addr_un);
39862 -#else
39863 -               /* stevens says: */
39864 -               servlen = proc->unixsocket->used + sizeof(fcgi_addr_un.sun_family);
39865 -#endif
39866 +
39867                 fcgi_addr = (struct sockaddr *) &fcgi_addr_un;
39868 -       
39869 +
39870                 if (buffer_is_empty(proc->connection_name)) {
39871                         /* on remote spawing we have to set the connection-name now */
39872                         buffer_copy_string(proc->connection_name, "unix:");
39873 @@ -1695,16 +1690,18 @@
39874  #endif
39875         } else {
39876                 fcgi_addr_in.sin_family = AF_INET;
39877 +
39878                 if (0 == inet_aton(host->host->ptr, &(fcgi_addr_in.sin_addr))) {
39879 -                       log_error_write(srv, __FILE__, __LINE__, "sbs", 
39880 -                                       "converting IP-adress failed for", host->host, 
39881 +                       log_error_write(srv, __FILE__, __LINE__, "sbs",
39882 +                                       "converting IP-adress failed for", host->host,
39883                                         "\nBe sure to specify an IP address here");
39884 -                       
39885 +
39886                         return -1;
39887                 }
39888 +
39889                 fcgi_addr_in.sin_port = htons(proc->port);
39890                 servlen = sizeof(fcgi_addr_in);
39891 -               
39892 +
39893                 fcgi_addr = (struct sockaddr *) &fcgi_addr_in;
39894  
39895                 if (buffer_is_empty(proc->connection_name)) {
39896 @@ -1715,20 +1712,20 @@
39897                         buffer_append_long(proc->connection_name, proc->port);
39898                 }
39899         }
39900 -       
39901 +
39902         if (-1 == connect(fcgi_fd, fcgi_addr, servlen)) {
39903 -               if (errno == EINPROGRESS || 
39904 +               if (errno == EINPROGRESS ||
39905                     errno == EALREADY ||
39906                     errno == EINTR) {
39907                         if (hctx->conf.debug > 2) {
39908 -                               log_error_write(srv, __FILE__, __LINE__, "sb", 
39909 +                               log_error_write(srv, __FILE__, __LINE__, "sb",
39910                                         "connect delayed, will continue later:", proc->connection_name);
39911                         }
39912 -                       
39913 +
39914                         return CONNECTION_DELAYED;
39915                 } else if (errno == EAGAIN) {
39916                         if (hctx->conf.debug) {
39917 -                               log_error_write(srv, __FILE__, __LINE__, "sbsd", 
39918 +                               log_error_write(srv, __FILE__, __LINE__, "sbsd",
39919                                         "This means that the you have more incoming requests than your fastcgi-backend can handle in parallel. "
39920                                         "Perhaps it helps to spawn more fastcgi backend or php-children, if not decrease server.max-connections."
39921                                         "The load for this fastcgi backend", proc->connection_name, "is", proc->load);
39922 @@ -1736,8 +1733,8 @@
39923  
39924                         return CONNECTION_OVERLOADED;
39925                 } else {
39926 -                       log_error_write(srv, __FILE__, __LINE__, "sssb", 
39927 -                                       "connect failed:", 
39928 +                       log_error_write(srv, __FILE__, __LINE__, "sssb",
39929 +                                       "connect failed:",
39930                                         strerror(errno), "on",
39931                                         proc->connection_name);
39932  
39933 @@ -1747,7 +1744,7 @@
39934  
39935         hctx->reconnects = 0;
39936         if (hctx->conf.debug > 1) {
39937 -               log_error_write(srv, __FILE__, __LINE__, "sd", 
39938 +               log_error_write(srv, __FILE__, __LINE__, "sd",
39939                                 "connect succeeded: ", fcgi_fd);
39940         }
39941  
39942 @@ -1756,21 +1753,21 @@
39943  
39944  static int fcgi_env_add_request_headers(server *srv, connection *con, plugin_data *p) {
39945         size_t i;
39946 -       
39947 +
39948         for (i = 0; i < con->request.headers->used; i++) {
39949                 data_string *ds;
39950 -               
39951 +
39952                 ds = (data_string *)con->request.headers->data[i];
39953 -               
39954 +
39955                 if (ds->value->used && ds->key->used) {
39956                         size_t j;
39957                         buffer_reset(srv->tmp_buf);
39958 -                       
39959 +
39960                         if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) {
39961                                 BUFFER_COPY_STRING_CONST(srv->tmp_buf, "HTTP_");
39962                                 srv->tmp_buf->used--;
39963                         }
39964 -                       
39965 +
39966                         buffer_prepare_append(srv->tmp_buf, ds->key->used + 2);
39967                         for (j = 0; j < ds->key->used - 1; j++) {
39968                                 char c = '_';
39969 @@ -1784,20 +1781,20 @@
39970                                 srv->tmp_buf->ptr[srv->tmp_buf->used++] = c;
39971                         }
39972                         srv->tmp_buf->ptr[srv->tmp_buf->used++] = '\0';
39973 -                       
39974 +
39975                         fcgi_env_add(p->fcgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value));
39976                 }
39977         }
39978 -       
39979 +
39980         for (i = 0; i < con->environment->used; i++) {
39981                 data_string *ds;
39982 -               
39983 +
39984                 ds = (data_string *)con->environment->data[i];
39985 -               
39986 +
39987                 if (ds->value->used && ds->key->used) {
39988                         size_t j;
39989                         buffer_reset(srv->tmp_buf);
39990 -                       
39991 +
39992                         buffer_prepare_append(srv->tmp_buf, ds->key->used + 2);
39993                         for (j = 0; j < ds->key->used - 1; j++) {
39994                                 char c = '_';
39995 @@ -1811,11 +1808,11 @@
39996                                 srv->tmp_buf->ptr[srv->tmp_buf->used++] = c;
39997                         }
39998                         srv->tmp_buf->ptr[srv->tmp_buf->used++] = '\0';
39999 -                       
40000 +
40001                         fcgi_env_add(p->fcgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value));
40002                 }
40003         }
40004 -       
40005 +
40006         return 0;
40007  }
40008  
40009 @@ -1824,24 +1821,24 @@
40010         FCGI_BeginRequestRecord beginRecord;
40011         FCGI_Header header;
40012         buffer *b;
40013 -       
40014 +
40015         char buf[32];
40016         const char *s;
40017  #ifdef HAVE_IPV6
40018         char b2[INET6_ADDRSTRLEN + 1];
40019  #endif
40020 -       
40021 +
40022         plugin_data *p    = hctx->plugin_data;
40023         fcgi_extension_host *host= hctx->host;
40024  
40025         connection *con   = hctx->remote_conn;
40026         server_socket *srv_sock = con->srv_socket;
40027 -       
40028 +
40029         sock_addr our_addr;
40030         socklen_t our_addr_len;
40031 -       
40032 +
40033         /* send FCGI_BEGIN_REQUEST */
40034 -       
40035 +
40036         fcgi_header(&(beginRecord.header), FCGI_BEGIN_REQUEST, request_id, sizeof(beginRecord.body), 0);
40037         beginRecord.body.roleB0 = host->mode;
40038         beginRecord.body.roleB1 = 0;
40039 @@ -1849,21 +1846,21 @@
40040         memset(beginRecord.body.reserved, 0, sizeof(beginRecord.body.reserved));
40041  
40042         b = chunkqueue_get_append_buffer(hctx->wb);
40043 -       
40044 +
40045         buffer_copy_memory(b, (const char *)&beginRecord, sizeof(beginRecord));
40046 -       
40047 +
40048         /* send FCGI_PARAMS */
40049         buffer_prepare_copy(p->fcgi_env, 1024);
40050  
40051  
40052         fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_NAME"/"PACKAGE_VERSION));
40053 -       
40054 +
40055         if (con->server_name->used) {
40056                 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_NAME"), CONST_BUF_LEN(con->server_name));
40057         } else {
40058  #ifdef HAVE_IPV6
40059 -               s = inet_ntop(srv_sock->addr.plain.sa_family, 
40060 -                             srv_sock->addr.plain.sa_family == AF_INET6 ? 
40061 +               s = inet_ntop(srv_sock->addr.plain.sa_family,
40062 +                             srv_sock->addr.plain.sa_family == AF_INET6 ?
40063                               (const void *) &(srv_sock->addr.ipv6.sin6_addr) :
40064                               (const void *) &(srv_sock->addr.ipv4.sin_addr),
40065                               b2, sizeof(b2)-1);
40066 @@ -1872,50 +1869,50 @@
40067  #endif
40068                 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_NAME"), s, strlen(s));
40069         }
40070 -       
40071 +
40072         fcgi_env_add(p->fcgi_env, CONST_STR_LEN("GATEWAY_INTERFACE"), CONST_STR_LEN("CGI/1.1"));
40073 -       
40074 -       ltostr(buf, 
40075 +
40076 +       ltostr(buf,
40077  #ifdef HAVE_IPV6
40078                ntohs(srv_sock->addr.plain.sa_family ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port)
40079  #else
40080                ntohs(srv_sock->addr.ipv4.sin_port)
40081  #endif
40082                );
40083 -       
40084 +
40085         fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_PORT"), buf, strlen(buf));
40086 -       
40087 +
40088         /* get the server-side of the connection to the client */
40089         our_addr_len = sizeof(our_addr);
40090 -       
40091 +
40092         if (-1 == getsockname(con->fd, &(our_addr.plain), &our_addr_len)) {
40093                 s = inet_ntop_cache_get_ip(srv, &(srv_sock->addr));
40094         } else {
40095                 s = inet_ntop_cache_get_ip(srv, &(our_addr));
40096         }
40097         fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_ADDR"), s, strlen(s));
40098 -       
40099 -       ltostr(buf, 
40100 +
40101 +       ltostr(buf,
40102  #ifdef HAVE_IPV6
40103                ntohs(con->dst_addr.plain.sa_family ? con->dst_addr.ipv6.sin6_port : con->dst_addr.ipv4.sin_port)
40104  #else
40105                ntohs(con->dst_addr.ipv4.sin_port)
40106  #endif
40107                );
40108 -       
40109 +
40110         fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REMOTE_PORT"), buf, strlen(buf));
40111 -       
40112 +
40113         s = inet_ntop_cache_get_ip(srv, &(con->dst_addr));
40114         fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REMOTE_ADDR"), s, strlen(s));
40115 -       
40116 +
40117         if (!buffer_is_empty(con->authed_user)) {
40118                 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REMOTE_USER"),
40119                              CONST_BUF_LEN(con->authed_user));
40120         }
40121 -       
40122 +
40123         if (con->request.content_length > 0 && host->mode != FCGI_AUTHORIZER) {
40124                 /* CGI-SPEC 6.1.2 and FastCGI spec 6.3 */
40125 -               
40126 +
40127                 /* request.content_length < SSIZE_MAX, see request.c */
40128                 ltostr(buf, con->request.content_length);
40129                 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("CONTENT_LENGTH"), buf, strlen(buf));
40130 @@ -1930,12 +1927,12 @@
40131                  */
40132  
40133                 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path));
40134 -               
40135 +
40136                 if (!buffer_is_empty(con->request.pathinfo)) {
40137                         fcgi_env_add(p->fcgi_env, CONST_STR_LEN("PATH_INFO"), CONST_BUF_LEN(con->request.pathinfo));
40138 -                       
40139 +
40140                         /* PATH_TRANSLATED is only defined if PATH_INFO is set */
40141 -                       
40142 +
40143                         if (!buffer_is_empty(host->docroot)) {
40144                                 buffer_copy_string_buffer(p->path, host->docroot);
40145                         } else {
40146 @@ -1957,27 +1954,27 @@
40147          */
40148  
40149         if (!buffer_is_empty(host->docroot)) {
40150 -               /* 
40151 -                * rewrite SCRIPT_FILENAME 
40152 -                * 
40153 +               /*
40154 +                * rewrite SCRIPT_FILENAME
40155 +                *
40156                  */
40157 -               
40158 +
40159                 buffer_copy_string_buffer(p->path, host->docroot);
40160                 buffer_append_string_buffer(p->path, con->uri.path);
40161 -               
40162 +
40163                 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path));
40164                 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(host->docroot));
40165         } else {
40166                 buffer_copy_string_buffer(p->path, con->physical.path);
40167 -               
40168 -               /* cgi.fix_pathinfo need a broken SCRIPT_FILENAME to find out what PATH_INFO is itself 
40169 -                * 
40170 +
40171 +               /* cgi.fix_pathinfo need a broken SCRIPT_FILENAME to find out what PATH_INFO is itself
40172 +                *
40173                  * see src/sapi/cgi_main.c, init_request_info()
40174                  */
40175                 if (host->break_scriptfilename_for_php) {
40176                         buffer_append_string_buffer(p->path, con->request.pathinfo);
40177                 }
40178 -               
40179 +
40180                 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path));
40181                 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(con->physical.doc_root));
40182         }
40183 @@ -1987,7 +1984,7 @@
40184                 /**
40185                  * /app1/index/list
40186                  *
40187 -                * stripping /app1 or /app1/ should lead to 
40188 +                * stripping /app1 or /app1/ should lead to
40189                  *
40190                  * /index/list
40191                  *
40192 @@ -2001,7 +1998,7 @@
40193                     0 == strncmp(con->request.orig_uri->ptr, host->strip_request_uri->ptr, host->strip_request_uri->used - 1)) {
40194                         /* the left is the same */
40195  
40196 -                       fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REQUEST_URI"), 
40197 +                       fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REQUEST_URI"),
40198                                         con->request.orig_uri->ptr + (host->strip_request_uri->used - 2),
40199                                         con->request.orig_uri->used - (host->strip_request_uri->used - 2));
40200                 } else {
40201 @@ -2018,26 +2015,26 @@
40202         } else {
40203                 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("QUERY_STRING"), CONST_STR_LEN(""));
40204         }
40205 -       
40206 +
40207         s = get_http_method_name(con->request.http_method);
40208         fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REQUEST_METHOD"), s, strlen(s));
40209         fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REDIRECT_STATUS"), CONST_STR_LEN("200")); /* if php is compiled with --force-redirect */
40210         s = get_http_version_name(con->request.http_version);
40211         fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_PROTOCOL"), s, strlen(s));
40212 -       
40213 +
40214  #ifdef USE_OPENSSL
40215         if (srv_sock->is_ssl) {
40216                 fcgi_env_add(p->fcgi_env, CONST_STR_LEN("HTTPS"), CONST_STR_LEN("on"));
40217         }
40218  #endif
40219 -       
40220 -       
40221 +
40222 +
40223         fcgi_env_add_request_headers(srv, con, p);
40224 -       
40225 +
40226         fcgi_header(&(header), FCGI_PARAMS, request_id, p->fcgi_env->used, 0);
40227         buffer_append_memory(b, (const char *)&header, sizeof(header));
40228         buffer_append_memory(b, (const char *)p->fcgi_env->ptr, p->fcgi_env->used);
40229 -       
40230 +
40231         fcgi_header(&(header), FCGI_PARAMS, request_id, 0, 0);
40232         buffer_append_memory(b, (const char *)&header, sizeof(header));
40233  
40234 @@ -2057,7 +2054,7 @@
40235  
40236                         /* we announce toWrite octects
40237                          * now take all the request_content chunk that we need to fill this request
40238 -                        * */   
40239 +                        * */
40240  
40241                         b = chunkqueue_get_append_buffer(hctx->wb);
40242                         fcgi_header(&(header), FCGI_STDIN, request_id, weWant, 0);
40243 @@ -2080,16 +2077,16 @@
40244                                         if (weHave > weWant - written) weHave = weWant - written;
40245  
40246                                         if (p->conf.debug > 10) {
40247 -                                               fprintf(stderr, "%s.%d: sending %lld bytes from (%lld / %lld) %s\n", 
40248 -                                                               __FILE__, __LINE__, 
40249 -                                                               weHave, 
40250 -                                                               req_c->offset, 
40251 -                                                               req_c->file.length, 
40252 +                                               fprintf(stderr, "%s.%d: sending %lld bytes from (%lld / %lld) %s\n",
40253 +                                                               __FILE__, __LINE__,
40254 +                                                               weHave,
40255 +                                                               req_c->offset,
40256 +                                                               req_c->file.length,
40257                                                                 req_c->file.name->ptr);
40258                                         }
40259  
40260                                         assert(weHave != 0);
40261 -                                       
40262 +
40263                                         chunkqueue_append_file(hctx->wb, req_c->file.name, req_c->offset, weHave);
40264  
40265                                         req_c->offset += weHave;
40266 @@ -2104,7 +2101,7 @@
40267                                          * - we reference the tempfile from the request-content-queue several times
40268                                          *   if the req_c is larger than FCGI_MAX_LENGTH
40269                                          * - we can't simply cleanup the request-content-queue as soon as possible
40270 -                                        *   as it would remove the tempfiles 
40271 +                                        *   as it would remove the tempfiles
40272                                          * - the idea is to 'steal' the tempfiles and attach the is_temp flag to the last
40273                                          *   referencing chunk of the fastcgi-write-queue
40274                                          *
40275 @@ -2141,7 +2138,7 @@
40276                                         req_c->offset += weHave;
40277                                         req_cq->bytes_out += weHave;
40278                                         written += weHave;
40279 -                                       
40280 +
40281                                         hctx->wb->bytes_in += weHave;
40282  
40283                                         if (req_c->offset == req_c->mem->used - 1) {
40284 @@ -2155,12 +2152,12 @@
40285                                         break;
40286                                 }
40287                         }
40288 -                       
40289 +
40290                         b->used++; /* add virtual \0 */
40291                         offset += weWant;
40292                 }
40293         }
40294 -       
40295 +
40296         b = chunkqueue_get_append_buffer(hctx->wb);
40297         /* terminate STDIN */
40298         fcgi_header(&(header), FCGI_STDIN, request_id, 0, 0);
40299 @@ -2175,118 +2172,19 @@
40300                 if ((i+1) % 16 == 0) {
40301                         size_t j;
40302                         for (j = i-15; j <= i; j++) {
40303 -                               fprintf(stderr, "%c", 
40304 +                               fprintf(stderr, "%c",
40305                                         isprint((unsigned char)hctx->write_buffer->ptr[j]) ? hctx->write_buffer->ptr[j] : '.');
40306                         }
40307                         fprintf(stderr, "\n");
40308                 }
40309         }
40310  #endif
40311 -       
40312 -       return 0;
40313 -}
40314  
40315 -static int fcgi_response_parse(server *srv, connection *con, plugin_data *p, buffer *in) {
40316 -       char *s, *ns;
40317 -       
40318 -       handler_ctx *hctx = con->plugin_ctx[p->id];
40319 -       fcgi_extension_host *host= hctx->host;
40320 -       
40321 -       UNUSED(srv);
40322 -
40323 -       buffer_copy_string_buffer(p->parse_response, in);
40324 -       
40325 -       /* search for \n */
40326 -       for (s = p->parse_response->ptr; NULL != (ns = strchr(s, '\n')); s = ns + 1) {
40327 -               char *key, *value;
40328 -               int key_len;
40329 -               data_string *ds;
40330 -               
40331 -               /* a good day. Someone has read the specs and is sending a \r\n to us */
40332 -               
40333 -               if (ns > p->parse_response->ptr &&
40334 -                   *(ns-1) == '\r') {
40335 -                       *(ns-1) = '\0';
40336 -               }
40337 -               
40338 -               ns[0] = '\0';
40339 -               
40340 -               key = s;
40341 -               if (NULL == (value = strchr(s, ':'))) {
40342 -                       /* we expect: "<key>: <value>\n" */
40343 -                       continue;
40344 -               }
40345 -               
40346 -               key_len = value - key;
40347 -               
40348 -               value++;
40349 -               /* strip WS */
40350 -               while (*value == ' ' || *value == '\t') value++;
40351 -               
40352 -               if (host->mode != FCGI_AUTHORIZER ||
40353 -                   !(con->http_status == 0 ||
40354 -                     con->http_status == 200)) {
40355 -                       /* authorizers shouldn't affect the response headers sent back to the client */
40356 -                       
40357 -                       /* don't forward Status: */
40358 -                       if (0 != strncasecmp(key, "Status", key_len)) {
40359 -                               if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
40360 -                                       ds = data_response_init();
40361 -                               }
40362 -                               buffer_copy_string_len(ds->key, key, key_len);
40363 -                               buffer_copy_string(ds->value, value);
40364 -                               
40365 -                               array_insert_unique(con->response.headers, (data_unset *)ds);
40366 -                       }
40367 -               }
40368 -               
40369 -               switch(key_len) {
40370 -               case 4:
40371 -                       if (0 == strncasecmp(key, "Date", key_len)) {
40372 -                               con->parsed_response |= HTTP_DATE;
40373 -                       }
40374 -                       break;
40375 -               case 6:
40376 -                       if (0 == strncasecmp(key, "Status", key_len)) {
40377 -                               con->http_status = strtol(value, NULL, 10);
40378 -                               con->parsed_response |= HTTP_STATUS;
40379 -                       }
40380 -                       break;
40381 -               case 8:
40382 -                       if (0 == strncasecmp(key, "Location", key_len)) {
40383 -                               con->parsed_response |= HTTP_LOCATION;
40384 -                       }
40385 -                       break;
40386 -               case 10:
40387 -                       if (0 == strncasecmp(key, "Connection", key_len)) {
40388 -                               con->response.keep_alive = (0 == strcasecmp(value, "Keep-Alive")) ? 1 : 0;
40389 -                               con->parsed_response |= HTTP_CONNECTION;
40390 -                       }
40391 -                       break;
40392 -               case 14:
40393 -                       if (0 == strncasecmp(key, "Content-Length", key_len)) {
40394 -                               con->response.content_length = strtol(value, NULL, 10);
40395 -                               con->parsed_response |= HTTP_CONTENT_LENGTH;
40396 -                               
40397 -                               if (con->response.content_length < 0) con->response.content_length = 0;
40398 -                       }
40399 -                       break;
40400 -               default:
40401 -                       break;
40402 -               }
40403 -       }
40404 -       
40405 -       /* CGI/1.1 rev 03 - 7.2.1.2 */
40406 -       if ((con->parsed_response & HTTP_LOCATION) &&
40407 -           !(con->parsed_response & HTTP_STATUS)) {
40408 -               con->http_status = 302;
40409 -       }
40410 -       
40411         return 0;
40412  }
40413  
40414  typedef struct {
40415 -       buffer  *b; 
40416 +       buffer  *b;
40417         size_t   len;
40418         int      type;
40419         int      padding;
40420 @@ -2327,9 +2225,9 @@
40421                 return -1;
40422         }
40423  
40424 -       /* we have at least a header, now check how much me have to fetch */ 
40425 +       /* we have at least a header, now check how much me have to fetch */
40426         header = (FCGI_Header *)(packet->b->ptr);
40427 -                       
40428 +
40429         packet->len = (header->contentLengthB0 | (header->contentLengthB1 << 8)) + header->paddingLength;
40430         packet->request_id = (header->requestIdB0 | (header->requestIdB1 << 8));
40431         packet->type = header->type;
40432 @@ -2348,7 +2246,7 @@
40433                         size_t weHave = c->mem->used - c->offset - offset - 1;
40434  
40435                         if (weHave > weWant) weHave = weWant;
40436 -                                               
40437 +
40438                         buffer_append_string_len(packet->b, c->mem->ptr + c->offset + offset, weHave);
40439  
40440                         /* we only skipped the first 8 bytes as they are the fcgi header */
40441 @@ -2380,65 +2278,37 @@
40442         }
40443  
40444         chunkqueue_remove_finished_chunks(hctx->rb);
40445 -       
40446 +
40447         return 0;
40448  }
40449  
40450  static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
40451         int fin = 0;
40452 -       int toread;
40453 -       ssize_t r;
40454 -       
40455 +
40456         plugin_data *p    = hctx->plugin_data;
40457         connection *con   = hctx->remote_conn;
40458 -       int fcgi_fd       = hctx->fd;
40459         fcgi_extension_host *host= hctx->host;
40460         fcgi_proc *proc   = hctx->proc;
40461 -       
40462 -       /* 
40463 -        * check how much we have to read 
40464 -        */
40465 -       if (ioctl(hctx->fd, FIONREAD, &toread)) {
40466 -               log_error_write(srv, __FILE__, __LINE__, "sd", 
40467 -                               "unexpected end-of-file (perhaps the fastcgi process died):",
40468 -                               fcgi_fd);
40469 -               return -1;
40470 -       }
40471 -       
40472 -       /* init read-buffer */
40473 -       
40474 -       if (toread > 0) {
40475 -               buffer *b;
40476  
40477 -               b = chunkqueue_get_append_buffer(hctx->rb);
40478 -               buffer_prepare_copy(b, toread + 1);
40479 -
40480 -               /* append to read-buffer */
40481 -               if (-1 == (r = read(hctx->fd, b->ptr, toread))) {
40482 -                       log_error_write(srv, __FILE__, __LINE__, "sds", 
40483 -                                       "unexpected end-of-file (perhaps the fastcgi process died):",
40484 -                                       fcgi_fd, strerror(errno));
40485 -                       return -1;
40486 -               }
40487 -               
40488 -               /* this should be catched by the b > 0 above */
40489 -               assert(r);
40490 -
40491 -               b->used = r + 1; /* one extra for the fake \0 */
40492 -               b->ptr[b->used - 1] = '\0';
40493 -       } else {
40494 -               log_error_write(srv, __FILE__, __LINE__, "ssdsb", 
40495 +       switch(srv->network_backend_read(srv, con, hctx->fd, hctx->rb)) {
40496 +       case NETWORK_STATUS_WAIT_FOR_EVENT:
40497 +               /* we are only triggered when there is a event */
40498 +               log_error_write(srv, __FILE__, __LINE__, "ssdsb",
40499                                 "unexpected end-of-file (perhaps the fastcgi process died):",
40500                                 "pid:", proc->pid,
40501                                 "socket:", proc->connection_name);
40502 -               
40503                 return -1;
40504 +       case NETWORK_STATUS_SUCCESS:
40505 +               break;
40506 +       default:
40507 +               log_error_write(srv, __FILE__, __LINE__, "s", "fastcgi-read failed");
40508 +               return -1;
40509         }
40510  
40511         /*
40512          * parse the fastcgi packets and forward the content to the write-queue
40513          *
40514 -        */     
40515 +        */
40516         while (fin == 0) {
40517                 fastcgi_response_packet packet;
40518  
40519 @@ -2454,92 +2324,135 @@
40520  
40521                         /* is the header already finished */
40522                         if (0 == con->file_started) {
40523 -                               char *c;
40524 -                               size_t blen;
40525 -                               data_string *ds;
40526 -                                       
40527 -                               /* search for header terminator 
40528 -                                * 
40529 -                                * if we start with \r\n check if last packet terminated with \r\n
40530 -                                * if we start with \n check if last packet terminated with \n
40531 -                                * search for \r\n\r\n
40532 -                                * search for \n\n
40533 -                                */
40534 +                               int have_content_length = 0;
40535 +                               int need_more = 0;
40536 +                               size_t i;
40537  
40538 -                               if (hctx->response_header->used == 0) {
40539 -                                       buffer_copy_string_buffer(hctx->response_header, packet.b);
40540 -                               } else {
40541 -                                       buffer_append_string_buffer(hctx->response_header, packet.b);
40542 -                               }
40543 +                               /* append the current packet to the chunk queue */
40544 +                               chunkqueue_append_buffer(hctx->http_rb, packet.b);
40545 +                               http_response_reset(p->resp);
40546  
40547 -                               if (NULL != (c = buffer_search_string_len(hctx->response_header, CONST_STR_LEN("\r\n\r\n")))) {
40548 -                                       blen = hctx->response_header->used - (c - hctx->response_header->ptr) - 4;
40549 -                                       hctx->response_header->used = (c - hctx->response_header->ptr) + 3;
40550 -                                       c += 4; /* point the the start of the response */
40551 -                               } else if (NULL != (c = buffer_search_string_len(hctx->response_header, CONST_STR_LEN("\n\n")))) {
40552 -                                       blen = hctx->response_header->used - (c - hctx->response_header->ptr) - 2;
40553 -                                       hctx->response_header->used = c - hctx->response_header->ptr + 2;
40554 -                                       c += 2; /* point the the start of the response */
40555 -                               } else {
40556 -                                       /* no luck, no header found */
40557 +                               switch(http_response_parse_cq(hctx->http_rb, p->resp)) {
40558 +                               case PARSE_ERROR:
40559 +                                       /* parsing the response header failed */
40560 +
40561 +                                       con->http_status = 502; /* Bad Gateway */
40562 +
40563 +                                       return 1;
40564 +                               case PARSE_NEED_MORE:
40565 +                                       need_more = 1;
40566 +                                       break; /* leave the loop */
40567 +                               case PARSE_SUCCESS:
40568                                         break;
40569 +                               default:
40570 +                                       /* should not happen */
40571 +                                       SEGFAULT();
40572                                 }
40573  
40574 -                               /* parse the response header */
40575 -                               fcgi_response_parse(srv, con, p, hctx->response_header);
40576 +                               if (need_more) break;
40577  
40578 -                               con->file_started = 1;
40579 +                               chunkqueue_remove_finished_chunks(hctx->http_rb);
40580  
40581 -                               if (host->mode == FCGI_AUTHORIZER &&
40582 -                                   (con->http_status == 0 ||
40583 -                                    con->http_status == 200)) {
40584 -                                       /* a authorizer with approved the static request, ignore the content here */
40585 -                                       hctx->send_content_body = 0;
40586 +                               con->http_status = p->resp->status;
40587 +
40588 +                               /* handle the header fields */
40589 +                               if (host->mode == FCGI_AUTHORIZER) {
40590 +                                       /* auth mode is a bit different */
40591 +
40592 +                                       if (con->http_status == 0 ||
40593 +                                           con->http_status == 200) {
40594 +                                               /* a authorizer with approved the static request, ignore the content here */
40595 +                                               hctx->send_content_body = 0;
40596 +                                       }
40597                                 }
40598  
40599 -                               if (host->allow_xsendfile &&
40600 -                                   NULL != (ds = (data_string *) array_get_element(con->response.headers, "X-LIGHTTPD-send-file"))) {
40601 -                                       stat_cache_entry *sce;
40602 +                               /* copy the http-headers */
40603 +                               for (i = 0; i < p->resp->headers->used; i++) {
40604 +                                       const char *ign[] = { "Status", NULL };
40605 +                                       size_t j;
40606 +                                       data_string *ds;
40607  
40608 -                                       if (HANDLER_ERROR != stat_cache_get_entry(srv, con, ds->value, &sce)) {
40609 -                                               /* found */
40610 +                                       data_string *header = (data_string *)p->resp->headers->data[i];
40611  
40612 -                                               http_chunk_append_file(srv, con, ds->value, 0, sce->st.st_size);
40613 -                                               hctx->send_content_body = 0; /* ignore the content */
40614 -                                               joblist_append(srv, con);
40615 +                                       /* ignore all headers in AUTHORIZER mode */
40616 +                                       if (host->mode == FCGI_AUTHORIZER) continue;
40617 +
40618 +                                       /* some headers are ignored by default */
40619 +                                       for (j = 0; ign[j]; j++) {
40620 +                                               if (0 == strcasecmp(ign[j], header->key->ptr)) break;
40621                                         }
40622 -                               }
40623 +                                       if (ign[j]) continue;
40624  
40625 +                                       if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Location"))) {
40626 +                                               /* CGI/1.1 rev 03 - 7.2.1.2 */
40627 +                                               con->http_status = 302;
40628 +                                       } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("Content-Length"))) {
40629 +                                               have_content_length = 1;
40630 +                                       } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("X-Sendfile")) || 
40631 +                                                  0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("X-LIGHTTPD-send-file"))) {
40632                                                 
40633 -                               if (hctx->send_content_body && blen > 1) {                                              
40634 -                                       /* enable chunked-transfer-encoding */
40635 +                                               stat_cache_entry *sce;
40636 +                                               
40637 +                                               if (host->allow_xsendfile &&
40638 +                                                   HANDLER_ERROR != stat_cache_get_entry(srv, con, header->value, &sce)) {
40639 +                                                       http_chunk_append_file(srv, con, header->value, 0, sce->st.st_size);
40640 +                                                       hctx->send_content_body = 0; /* ignore the content */
40641 +                                       
40642 +                                                       joblist_append(srv, con);
40643 +                                               }
40644 +
40645 +                                               continue; /* ignore header */
40646 +                                       }
40647 +                                       
40648 +                                       if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
40649 +                                               ds = data_response_init();
40650 +                                       }
40651 +                                       buffer_copy_string_buffer(ds->key, header->key);
40652 +                                       buffer_copy_string_buffer(ds->value, header->value);
40653 +
40654 +                                       array_insert_unique(con->response.headers, (data_unset *)ds);
40655 +                               }
40656 +
40657 +                               /* header is complete ... go on with the body */
40658 +
40659 +                               con->file_started = 1;
40660 +
40661 +                               if (hctx->send_content_body) {
40662 +                                       chunk *c = hctx->http_rb->first;
40663 +
40664 +                                       /* if we don't have a content-length enable chunked encoding 
40665 +                                        * if possible
40666 +                                        * 
40667 +                                        * TODO: move this to a later stage in the filter-queue
40668 +                                        *  */
40669                                         if (con->request.http_version == HTTP_VERSION_1_1 &&
40670 -                                           !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
40671 +                                           !have_content_length) {
40672                                                 con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
40673                                         }
40674  
40675 -                                       http_chunk_append_mem(srv, con, c, blen);
40676 +                                       /* copy the rest of the data */
40677 +                                       for (c = hctx->http_rb->first; c; c = c->next) {
40678 +                                               if (c->mem->used > 1) {
40679 +                                                       http_chunk_append_mem(srv, con, c->mem->ptr + c->offset, c->mem->used - c->offset);
40680 +                                                       c->offset = c->mem->used - 1;
40681 +                                               }
40682 +                                       }
40683 +                                       chunkqueue_remove_finished_chunks(hctx->http_rb);
40684                                         joblist_append(srv, con);
40685                                 }
40686                         } else if (hctx->send_content_body && packet.b->used > 1) {
40687 -                               if (con->request.http_version == HTTP_VERSION_1_1 &&
40688 -                                   !(con->parsed_response & HTTP_CONTENT_LENGTH)) {
40689 -                                       /* enable chunked-transfer-encoding */
40690 -                                       con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
40691 -                               }
40692 -
40693                                 http_chunk_append_mem(srv, con, packet.b->ptr, packet.b->used);
40694                                 joblist_append(srv, con);
40695                         }
40696                         break;
40697                 case FCGI_STDERR:
40698 -                       log_error_write(srv, __FILE__, __LINE__, "sb", 
40699 +                       log_error_write(srv, __FILE__, __LINE__, "sb",
40700                                         "FastCGI-stderr:", packet.b);
40701 -                       
40702 +
40703                         break;
40704                 case FCGI_END_REQUEST:
40705                         con->file_finished = 1;
40706 -                       
40707 +
40708                         if (host->mode != FCGI_AUTHORIZER ||
40709                             !(con->http_status == 0 ||
40710                               con->http_status == 200)) {
40711 @@ -2547,39 +2460,39 @@
40712                                 http_chunk_append_mem(srv, con, NULL, 0);
40713                                 joblist_append(srv, con);
40714                         }
40715 -                       
40716 +
40717                         fin = 1;
40718                         break;
40719                 default:
40720 -                       log_error_write(srv, __FILE__, __LINE__, "sd", 
40721 +                       log_error_write(srv, __FILE__, __LINE__, "sd",
40722                                         "FastCGI: header.type not handled: ", packet.type);
40723                         break;
40724                 }
40725                 buffer_free(packet.b);
40726         }
40727 -       
40728 +
40729         return fin;
40730  }
40731  
40732  static int fcgi_restart_dead_procs(server *srv, plugin_data *p, fcgi_extension_host *host) {
40733         fcgi_proc *proc;
40734 -       
40735 +
40736         for (proc = host->first; proc; proc = proc->next) {
40737                 int status;
40738  
40739                 if (p->conf.debug > 2) {
40740 -                       log_error_write(srv, __FILE__, __LINE__,  "sbdddd", 
40741 -                                       "proc:", 
40742 +                       log_error_write(srv, __FILE__, __LINE__,  "sbdddd",
40743 +                                       "proc:",
40744                                         proc->connection_name,
40745                                         proc->state,
40746                                         proc->is_local,
40747                                         proc->load,
40748                                         proc->pid);
40749                 }
40750 -               
40751 -               /* 
40752 +
40753 +               /*
40754                  * if the remote side is overloaded, we check back after <n> seconds
40755 -                * 
40756 +                *
40757                  */
40758                 switch (proc->state) {
40759                 case PROC_STATE_KILLED:
40760 @@ -2592,13 +2505,13 @@
40761                         break;
40762                 case PROC_STATE_OVERLOADED:
40763                         if (srv->cur_ts <= proc->disabled_until) break;
40764 -                       
40765 +
40766                         proc->state = PROC_STATE_RUNNING;
40767                         host->active_procs++;
40768 -                       
40769 -                       log_error_write(srv, __FILE__, __LINE__,  "sbdb", 
40770 -                                       "fcgi-server re-enabled:", 
40771 -                                       host->host, host->port, 
40772 +
40773 +                       log_error_write(srv, __FILE__, __LINE__,  "sbdb",
40774 +                                       "fcgi-server re-enabled:",
40775 +                                       host->host, host->port,
40776                                         host->unixsocket);
40777                         break;
40778                 case PROC_STATE_DIED_WAIT_FOR_PID:
40779 @@ -2606,7 +2519,7 @@
40780                         if (!proc->is_local) break;
40781  
40782                         /* the child should not terminate at all */
40783 -                       
40784 +#ifndef _WIN32
40785                         switch(waitpid(proc->pid, &status, WNOHANG)) {
40786                         case 0:
40787                                 /* child is still alive */
40788 @@ -2616,45 +2529,45 @@
40789                         default:
40790                                 if (WIFEXITED(status)) {
40791  #if 0
40792 -                                       log_error_write(srv, __FILE__, __LINE__, "sdsd", 
40793 +                                       log_error_write(srv, __FILE__, __LINE__, "sdsd",
40794                                                         "child exited, pid:", proc->pid,
40795                                                         "status:", WEXITSTATUS(status));
40796  #endif
40797                                 } else if (WIFSIGNALED(status)) {
40798 -                                       log_error_write(srv, __FILE__, __LINE__, "sd", 
40799 -                                                       "child signaled:", 
40800 +                                       log_error_write(srv, __FILE__, __LINE__, "sd",
40801 +                                                       "child signaled:",
40802                                                         WTERMSIG(status));
40803                                 } else {
40804 -                                       log_error_write(srv, __FILE__, __LINE__, "sd", 
40805 -                                                       "child died somehow:", 
40806 +                                       log_error_write(srv, __FILE__, __LINE__, "sd",
40807 +                                                       "child died somehow:",
40808                                                         status);
40809                                 }
40810 -                               
40811 +
40812                                 proc->state = PROC_STATE_DIED;
40813                                 break;
40814                         }
40815 -
40816 +#endif
40817                         /* fall through if we have a dead proc now */
40818                         if (proc->state != PROC_STATE_DIED) break;
40819  
40820                 case PROC_STATE_DIED:
40821 -                       /* local proc get restarted by us, 
40822 +                       /* local proc get restarted by us,
40823                          * remote ones hopefully by the admin */
40824 -                       
40825 +
40826                         if (proc->is_local) {
40827                                 /* we still have connections bound to this proc,
40828                                  * let them terminate first */
40829                                 if (proc->load != 0) break;
40830 -                       
40831 +
40832                                 /* restart the child */
40833 -                               
40834 +
40835                                 if (p->conf.debug) {
40836                                         log_error_write(srv, __FILE__, __LINE__, "ssbsdsd",
40837                                                         "--- fastcgi spawning",
40838                                                         "\n\tsocket", proc->connection_name,
40839                                                         "\n\tcurrent:", 1, "/", host->min_procs);
40840                                 }
40841 -                               
40842 +
40843                                 if (fcgi_spawn_connection(srv, p, host, proc)) {
40844                                         log_error_write(srv, __FILE__, __LINE__, "s",
40845                                                         "ERROR: spawning fcgi failed.");
40846 @@ -2662,18 +2575,18 @@
40847                                 }
40848                         } else {
40849                                 if (srv->cur_ts <= proc->disabled_until) break;
40850 -                       
40851 +
40852                                 proc->state = PROC_STATE_RUNNING;
40853                                 host->active_procs++;
40854 -                       
40855 -                               log_error_write(srv, __FILE__, __LINE__,  "sb", 
40856 -                                               "fcgi-server re-enabled:", 
40857 +
40858 +                               log_error_write(srv, __FILE__, __LINE__,  "sb",
40859 +                                               "fcgi-server re-enabled:",
40860                                                 proc->connection_name);
40861                         }
40862                         break;
40863                 }
40864         }
40865 -       
40866 +
40867         return 0;
40868  }
40869  
40870 @@ -2682,19 +2595,19 @@
40871         fcgi_extension_host *host= hctx->host;
40872         connection *con   = hctx->remote_conn;
40873         fcgi_proc  *proc;
40874 -       
40875 +
40876         int ret;
40877  
40878 -       /* sanity check */      
40879 +       /* sanity check */
40880         if (!host ||
40881             ((!host->host->used || !host->port) && !host->unixsocket->used)) {
40882 -               log_error_write(srv, __FILE__, __LINE__, "sxddd", 
40883 +               log_error_write(srv, __FILE__, __LINE__, "sxddd",
40884                                 "write-req: error",
40885                                 host,
40886                                 host->host->used,
40887                                 host->port,
40888                                 host->unixsocket->used);
40889 -                       
40890 +
40891                 hctx->proc->disabled_until = srv->cur_ts + 10;
40892                 hctx->proc->state = PROC_STATE_DIED;
40893  
40894 @@ -2705,12 +2618,12 @@
40895         if (hctx->state == FCGI_STATE_CONNECT_DELAYED) {
40896                 int socket_error;
40897                 socklen_t socket_error_len = sizeof(socket_error);
40898 -                       
40899 +
40900                 /* try to finish the connect() */
40901                 if (0 != getsockopt(hctx->fd, SOL_SOCKET, SO_ERROR, &socket_error, &socket_error_len)) {
40902 -                       log_error_write(srv, __FILE__, __LINE__, "ss", 
40903 +                       log_error_write(srv, __FILE__, __LINE__, "ss",
40904                                         "getsockopt failed:", strerror(errno));
40905 -                       
40906 +
40907                         hctx->proc->disabled_until = srv->cur_ts + 10;
40908                         hctx->proc->state = PROC_STATE_DIED;
40909  
40910 @@ -2719,12 +2632,12 @@
40911                 if (socket_error != 0) {
40912                         if (!hctx->proc->is_local || p->conf.debug) {
40913                                 /* local procs get restarted */
40914 -                               
40915 +
40916                                 log_error_write(srv, __FILE__, __LINE__, "sssb",
40917 -                                               "establishing connection failed:", strerror(socket_error), 
40918 +                                               "establishing connection failed:", strerror(socket_error),
40919                                                 "socket:", hctx->proc->connection_name);
40920                         }
40921 -       
40922 +
40923                         hctx->proc->disabled_until = srv->cur_ts + 5;
40924  
40925                         if (hctx->proc->is_local) {
40926 @@ -2732,17 +2645,17 @@
40927                         } else {
40928                                 hctx->proc->state = PROC_STATE_DIED;
40929                         }
40930 -       
40931 +
40932                         hctx->proc->state = PROC_STATE_DIED;
40933 -               
40934 +
40935                         fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
40936                         buffer_append_string(p->statuskey, ".died");
40937  
40938                         status_counter_inc(srv, CONST_BUF_LEN(p->statuskey));
40939 -               
40940 +
40941                         return HANDLER_ERROR;
40942                 }
40943 -               /* go on with preparing the request */ 
40944 +               /* go on with preparing the request */
40945                 hctx->state = FCGI_STATE_PREPARE_WRITE;
40946         }
40947  
40948 @@ -2755,14 +2668,14 @@
40949                 /* do we have a running process for this host (max-procs) ? */
40950                 hctx->proc = NULL;
40951  
40952 -               for (proc = hctx->host->first; 
40953 -                    proc && proc->state != PROC_STATE_RUNNING; 
40954 +               for (proc = hctx->host->first;
40955 +                    proc && proc->state != PROC_STATE_RUNNING;
40956                      proc = proc->next);
40957 -                       
40958 +
40959                 /* all childs are dead */
40960                 if (proc == NULL) {
40961                         hctx->fde_ndx = -1;
40962 -               
40963 +
40964                         return HANDLER_ERROR;
40965                 }
40966  
40967 @@ -2775,50 +2688,50 @@
40968                 }
40969  
40970                 ret = host->unixsocket->used ? AF_UNIX : AF_INET;
40971 -               
40972 +
40973                 if (-1 == (hctx->fd = socket(ret, SOCK_STREAM, 0))) {
40974                         if (errno == EMFILE ||
40975                             errno == EINTR) {
40976 -                               log_error_write(srv, __FILE__, __LINE__, "sd", 
40977 +                               log_error_write(srv, __FILE__, __LINE__, "sd",
40978                                                 "wait for fd at connection:", con->fd);
40979 -                               
40980 +
40981                                 return HANDLER_WAIT_FOR_FD;
40982                         }
40983 -                       
40984 -                       log_error_write(srv, __FILE__, __LINE__, "ssdd", 
40985 +
40986 +                       log_error_write(srv, __FILE__, __LINE__, "ssdd",
40987                                         "socket failed:", strerror(errno), srv->cur_fds, srv->max_fds);
40988                         return HANDLER_ERROR;
40989                 }
40990                 hctx->fde_ndx = -1;
40991 -               
40992 +
40993                 srv->cur_fds++;
40994 -               
40995 +
40996                 fdevent_register(srv->ev, hctx->fd, fcgi_handle_fdevent, hctx);
40997 -               
40998 +
40999                 if (-1 == fdevent_fcntl_set(srv->ev, hctx->fd)) {
41000 -                       log_error_write(srv, __FILE__, __LINE__, "ss", 
41001 +                       log_error_write(srv, __FILE__, __LINE__, "ss",
41002                                         "fcntl failed:", strerror(errno));
41003 -                       
41004 +
41005                         return HANDLER_ERROR;
41006                 }
41007 -                       
41008 +
41009                 if (hctx->proc->is_local) {
41010                         hctx->pid = hctx->proc->pid;
41011                 }
41012 -                       
41013 +
41014                 switch (fcgi_establish_connection(srv, hctx)) {
41015                 case CONNECTION_DELAYED:
41016                         /* connection is in progress, wait for an event and call getsockopt() below */
41017 -                       
41018 +
41019                         fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
41020 -                       
41021 +
41022                         fcgi_set_state(srv, hctx, FCGI_STATE_CONNECT_DELAYED);
41023                         return HANDLER_WAIT_FOR_EVENT;
41024                 case CONNECTION_OVERLOADED:
41025                         /* cool down the backend, it is overloaded
41026                          * -> EAGAIN */
41027  
41028 -                       log_error_write(srv, __FILE__, __LINE__, "ssdsd", 
41029 +                       log_error_write(srv, __FILE__, __LINE__, "ssdsd",
41030                                 "backend is overloaded, we disable it for a 2 seconds and send the request to another backend instead:",
41031                                 "reconnects:", hctx->reconnects,
41032                                 "load:", host->load);
41033 @@ -2831,7 +2744,7 @@
41034                         buffer_append_string(p->statuskey, ".overloaded");
41035  
41036                         status_counter_inc(srv, CONST_BUF_LEN(p->statuskey));
41037 -                       
41038 +
41039                         return HANDLER_ERROR;
41040                 case CONNECTION_DEAD:
41041                         /* we got a hard error from the backend like
41042 @@ -2840,19 +2753,19 @@
41043                          *
41044                          * for check if the host is back in 5 seconds
41045                          *  */
41046 -                       
41047 +
41048                         hctx->proc->disabled_until = srv->cur_ts + 5;
41049                         if (hctx->proc->is_local) {
41050                                 hctx->proc->state = PROC_STATE_DIED_WAIT_FOR_PID;
41051                         } else {
41052                                 hctx->proc->state = PROC_STATE_DIED;
41053                         }
41054 -       
41055 -                       log_error_write(srv, __FILE__, __LINE__, "ssdsd", 
41056 +
41057 +                       log_error_write(srv, __FILE__, __LINE__, "ssdsd",
41058                                 "backend died, we disable it for a 5 seconds and send the request to another backend instead:",
41059                                 "reconnects:", hctx->reconnects,
41060                                 "load:", host->load);
41061 -       
41062 +
41063                         fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
41064                         buffer_append_string(p->statuskey, ".died");
41065  
41066 @@ -2863,19 +2776,19 @@
41067                         /* everything is ok, go on */
41068  
41069                         fcgi_set_state(srv, hctx, FCGI_STATE_PREPARE_WRITE);
41070 -                       
41071 +
41072                         break;
41073                 case CONNECTION_UNSET:
41074                         break;
41075                 }
41076 -               
41077 +
41078         case FCGI_STATE_PREPARE_WRITE:
41079                 /* ok, we have the connection */
41080 -               
41081 +
41082                 hctx->proc->load++;
41083                 hctx->proc->last_used = srv->cur_ts;
41084                 hctx->got_proc = 1;
41085 -       
41086 +
41087                 status_counter_inc(srv, CONST_STR_LEN("fastcgi.requests"));
41088                 status_counter_inc(srv, CONST_STR_LEN("fastcgi.active-requests"));
41089  
41090 @@ -2898,9 +2811,9 @@
41091  
41092                 if (p->conf.debug) {
41093                         log_error_write(srv, __FILE__, __LINE__, "ssdsbsd",
41094 -                                       "got proc:", 
41095 -                                       "pid:", hctx->proc->pid, 
41096 -                                       "socket:", hctx->proc->connection_name, 
41097 +                                       "got proc:",
41098 +                                       "pid:", hctx->proc->pid,
41099 +                                       "socket:", hctx->proc->connection_name,
41100                                         "load:", hctx->proc->load);
41101                 }
41102  
41103 @@ -2908,62 +2821,63 @@
41104                 if (hctx->request_id == 0) {
41105                         hctx->request_id = fcgi_requestid_new(srv, p);
41106                 } else {
41107 -                       log_error_write(srv, __FILE__, __LINE__, "sd", 
41108 +                       log_error_write(srv, __FILE__, __LINE__, "sd",
41109                                         "fcgi-request is already in use:", hctx->request_id);
41110                 }
41111 -               
41112 +
41113                 /* fall through */
41114                 fcgi_create_env(srv, hctx, hctx->request_id);
41115 -               
41116 +
41117                 fcgi_set_state(srv, hctx, FCGI_STATE_WRITE);
41118 -               
41119 +
41120                 /* fall through */
41121         case FCGI_STATE_WRITE:
41122 -               ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb); 
41123 +               ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb);
41124  
41125                 chunkqueue_remove_finished_chunks(hctx->wb);
41126 -               
41127 +
41128                 if (ret < 0) {
41129                         switch(errno) {
41130                         case ENOTCONN:
41131 -                               /* the connection got dropped after accept() 
41132 -                                * 
41133 -                                * this is most of the time a PHP which dies 
41134 +                               /* the connection got dropped after accept()
41135 +                                *
41136 +                                * this is most of the time a PHP which dies
41137                                  * after PHP_FCGI_MAX_REQUESTS
41138 -                                * 
41139 -                                */ 
41140 +                                *
41141 +                                */
41142                                 if (hctx->wb->bytes_out == 0 &&
41143                                     hctx->reconnects < 5) {
41144 -                                       usleep(10000); /* take away the load of the webserver 
41145 -                                                       * to let the php a chance to restart 
41146 +#ifndef _WIN32
41147 +                                       usleep(10000); /* take away the load of the webserver
41148 +                                                       * to let the php a chance to restart
41149                                                         */
41150 -                                       
41151 +#endif
41152                                         fcgi_reconnect(srv, hctx);
41153 -                               
41154 +
41155                                         return HANDLER_WAIT_FOR_FD;
41156                                 }
41157 -                               
41158 +
41159                                 /* not reconnected ... why
41160 -                                * 
41161 +                                *
41162                                  * far@#lighttpd report this for FreeBSD
41163 -                                * 
41164 +                                *
41165                                  */
41166 -                               
41167 -                               log_error_write(srv, __FILE__, __LINE__, "ssdsd", 
41168 +
41169 +                               log_error_write(srv, __FILE__, __LINE__, "ssosd",
41170                                                 "[REPORT ME] connection was dropped after accept(). reconnect() denied:",
41171                                                 "write-offset:", hctx->wb->bytes_out,
41172                                                 "reconnect attempts:", hctx->reconnects);
41173 -                               
41174 +
41175                                 return HANDLER_ERROR;
41176                         case EAGAIN:
41177                         case EINTR:
41178                                 fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
41179 -                               
41180 +
41181                                 return HANDLER_WAIT_FOR_EVENT;
41182                         default:
41183 -                               log_error_write(srv, __FILE__, __LINE__, "ssd", 
41184 +                               log_error_write(srv, __FILE__, __LINE__, "ssd",
41185                                                 "write failed:", strerror(errno), errno);
41186 -                               
41187 +
41188                                 return HANDLER_ERROR;
41189                         }
41190                 }
41191 @@ -2975,7 +2889,7 @@
41192                         fcgi_set_state(srv, hctx, FCGI_STATE_READ);
41193                 } else {
41194                         fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
41195 -                               
41196 +
41197                         return HANDLER_WAIT_FOR_EVENT;
41198                 }
41199  
41200 @@ -2987,7 +2901,7 @@
41201                 log_error_write(srv, __FILE__, __LINE__, "s", "(debug) unknown state");
41202                 return HANDLER_ERROR;
41203         }
41204 -       
41205 +
41206         return HANDLER_WAIT_FOR_EVENT;
41207  }
41208  
41209 @@ -2996,18 +2910,18 @@
41210   * */
41211  SUBREQUEST_FUNC(mod_fastcgi_handle_subrequest) {
41212         plugin_data *p = p_d;
41213 -       
41214 +
41215         handler_ctx *hctx = con->plugin_ctx[p->id];
41216         fcgi_proc *proc;
41217         fcgi_extension_host *host;
41218 -       
41219 +
41220         if (NULL == hctx) return HANDLER_GO_ON;
41221 -       
41222 +
41223         /* not my job */
41224         if (con->mode != p->id) return HANDLER_GO_ON;
41225  
41226         /* we don't have a host yet, choose one
41227 -        * -> this happens in the first round 
41228 +        * -> this happens in the first round
41229          *    and when the host died and we have to select a new one */
41230         if (hctx->host == NULL) {
41231                 size_t k;
41232 @@ -3016,23 +2930,23 @@
41233                 /* get best server */
41234                 for (k = 0, ndx = -1; k < hctx->ext->used; k++) {
41235                         host = hctx->ext->hosts[k];
41236 -               
41237 +
41238                         /* we should have at least one proc that can do something */
41239                         if (host->active_procs == 0) continue;
41240  
41241                         if (used == -1 || host->load < used) {
41242                                 used = host->load;
41243 -                       
41244 +
41245                                 ndx = k;
41246                         }
41247                 }
41248 -       
41249 +
41250                 /* found a server */
41251                 if (ndx == -1) {
41252                         /* all hosts are down */
41253  
41254                         fcgi_connection_close(srv, hctx);
41255 -                       
41256 +
41257                         con->http_status = 500;
41258                         con->mode = DIRECT;
41259  
41260 @@ -3040,16 +2954,16 @@
41261                 }
41262  
41263                 host = hctx->ext->hosts[ndx];
41264 -               
41265 -               /* 
41266 -                * if check-local is disabled, use the uri.path handler 
41267 -                * 
41268 +
41269 +               /*
41270 +                * if check-local is disabled, use the uri.path handler
41271 +                *
41272                  */
41273 -               
41274 +
41275                 /* init handler-context */
41276                 hctx->host = host;
41277  
41278 -               /* we put a connection on this host, move the other new connections to other hosts 
41279 +               /* we put a connection on this host, move the other new connections to other hosts
41280                  *
41281                  * as soon as hctx->host is unassigned, decrease the load again */
41282                 hctx->host->load++;
41283 @@ -3063,7 +2977,7 @@
41284         case HANDLER_ERROR:
41285                 proc = hctx->proc;
41286                 host = hctx->host;
41287 -               
41288 +
41289                 if (hctx->state == FCGI_STATE_INIT ||
41290                     hctx->state == FCGI_STATE_CONNECT_DELAYED) {
41291                         if (proc) host->active_procs--;
41292 @@ -3078,7 +2992,7 @@
41293                                 return HANDLER_WAIT_FOR_FD;
41294                         } else {
41295                                 fcgi_connection_close(srv, hctx);
41296 -                       
41297 +
41298                                 buffer_reset(con->physical.path);
41299                                 con->mode = DIRECT;
41300                                 con->http_status = 500;
41301 @@ -3088,12 +3002,12 @@
41302                         }
41303                 } else {
41304                         fcgi_connection_close(srv, hctx);
41305 -                       
41306 +
41307                         buffer_reset(con->physical.path);
41308                         con->mode = DIRECT;
41309                         con->http_status = 503;
41310                         joblist_append(srv, con); /* really ? */
41311 -                       
41312 +
41313                         return HANDLER_FINISHED;
41314                 }
41315         case HANDLER_WAIT_FOR_EVENT:
41316 @@ -3115,7 +3029,7 @@
41317         handler_ctx *hctx = ctx;
41318         connection  *con  = hctx->remote_conn;
41319         plugin_data *p    = hctx->plugin_data;
41320 -       
41321 +
41322         fcgi_proc *proc   = hctx->proc;
41323         fcgi_extension_host *host= hctx->host;
41324  
41325 @@ -3125,8 +3039,8 @@
41326                 case 0:
41327                         break;
41328                 case 1:
41329 -                       
41330 -                       if (host->mode == FCGI_AUTHORIZER && 
41331 +
41332 +                       if (host->mode == FCGI_AUTHORIZER &&
41333                             (con->http_status == 200 ||
41334                              con->http_status == 0)) {
41335                                 /*
41336 @@ -3136,26 +3050,26 @@
41337                                  */
41338  
41339                                 buffer_copy_string_buffer(con->physical.doc_root, host->docroot);
41340 -                               
41341 +
41342                                 buffer_copy_string_buffer(con->physical.path, host->docroot);
41343                                 buffer_append_string_buffer(con->physical.path, con->uri.path);
41344                                 fcgi_connection_close(srv, hctx);
41345 -                               
41346 +
41347                                 con->mode = DIRECT;
41348                                 con->file_started = 1; /* fcgi_extension won't touch the request afterwards */
41349                         } else {
41350                                 /* we are done */
41351                                 fcgi_connection_close(srv, hctx);
41352                         }
41353 -                       
41354 +
41355                         joblist_append(srv, con);
41356                         return HANDLER_FINISHED;
41357                 case -1:
41358                         if (proc->pid && proc->state != PROC_STATE_DIED) {
41359                                 int status;
41360 -                               
41361 +
41362                                 /* only fetch the zombie if it is not already done */
41363 -                               
41364 +#ifndef _WIN32
41365                                 switch(waitpid(proc->pid, &status, WNOHANG)) {
41366                                 case 0:
41367                                         /* child is still alive */
41368 @@ -3165,60 +3079,61 @@
41369                                 default:
41370                                         /* the child should not terminate at all */
41371                                         if (WIFEXITED(status)) {
41372 -                                               log_error_write(srv, __FILE__, __LINE__, "sdsd", 
41373 +                                               log_error_write(srv, __FILE__, __LINE__, "sdsd",
41374                                                                 "child exited, pid:", proc->pid,
41375                                                                 "status:", WEXITSTATUS(status));
41376                                         } else if (WIFSIGNALED(status)) {
41377 -                                               log_error_write(srv, __FILE__, __LINE__, "sd", 
41378 -                                                               "child signaled:", 
41379 +                                               log_error_write(srv, __FILE__, __LINE__, "sd",
41380 +                                                               "child signaled:",
41381                                                                 WTERMSIG(status));
41382                                         } else {
41383 -                                               log_error_write(srv, __FILE__, __LINE__, "sd", 
41384 -                                                               "child died somehow:", 
41385 +                                               log_error_write(srv, __FILE__, __LINE__, "sd",
41386 +                                                               "child died somehow:",
41387                                                                 status);
41388                                         }
41389 -                                       
41390 +
41391                                         if (p->conf.debug) {
41392                                                 log_error_write(srv, __FILE__, __LINE__, "ssbsdsd",
41393                                                                 "--- fastcgi spawning",
41394                                                                 "\n\tsocket", proc->connection_name,
41395                                                                 "\n\tcurrent:", 1, "/", host->min_procs);
41396                                         }
41397 -                                       
41398 +
41399                                         if (fcgi_spawn_connection(srv, p, host, proc)) {
41400                                                 /* respawning failed, retry later */
41401                                                 proc->state = PROC_STATE_DIED;
41402  
41403 -                                               log_error_write(srv, __FILE__, __LINE__, "s", 
41404 +                                               log_error_write(srv, __FILE__, __LINE__, "s",
41405                                                                 "respawning failed, will retry later");
41406                                         }
41407 -                                       
41408 +
41409                                         break;
41410                                 }
41411 +#endif
41412                         }
41413  
41414                         if (con->file_started == 0) {
41415                                 /* nothing has been send out yet, try to use another child */
41416 -                               
41417 +
41418                                 if (hctx->wb->bytes_out == 0 &&
41419                                     hctx->reconnects < 5) {
41420                                         fcgi_reconnect(srv, hctx);
41421 -                                       
41422 -                                       log_error_write(srv, __FILE__, __LINE__, "ssbsbs", 
41423 +
41424 +                                       log_error_write(srv, __FILE__, __LINE__, "ssbsbs",
41425                                                 "response not received, request not sent",
41426 -                                               "on socket:", proc->connection_name, 
41427 +                                               "on socket:", proc->connection_name,
41428                                                 "for", con->uri.path, ", reconnecting");
41429 -                                       
41430 +
41431                                         return HANDLER_WAIT_FOR_FD;
41432                                 }
41433 -                       
41434 -                               log_error_write(srv, __FILE__, __LINE__, "sosbsbs", 
41435 +
41436 +                               log_error_write(srv, __FILE__, __LINE__, "sosbsbs",
41437                                                 "response not received, request sent:", hctx->wb->bytes_out,
41438 -                                               "on socket:", proc->connection_name, 
41439 +                                               "on socket:", proc->connection_name,
41440                                                 "for", con->uri.path, ", closing connection");
41441 -                               
41442 +
41443                                 fcgi_connection_close(srv, hctx);
41444 -                               
41445 +
41446                                 connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST);
41447                                 buffer_reset(con->physical.path);
41448                                 con->http_status = 500;
41449 @@ -3226,76 +3141,76 @@
41450                         } else {
41451                                 /* response might have been already started, kill the connection */
41452                                 fcgi_connection_close(srv, hctx);
41453 -                               
41454 -                               log_error_write(srv, __FILE__, __LINE__, "ssbsbs", 
41455 +
41456 +                               log_error_write(srv, __FILE__, __LINE__, "ssbsbs",
41457                                                 "response already sent out, but backend returned error",
41458 -                                               "on socket:", proc->connection_name, 
41459 +                                               "on socket:", proc->connection_name,
41460                                                 "for", con->uri.path, ", terminating connection");
41461 -                               
41462 +
41463                                 connection_set_state(srv, con, CON_STATE_ERROR);
41464                         }
41465  
41466                         /* */
41467 -                       
41468 -                       
41469 +
41470 +
41471                         joblist_append(srv, con);
41472                         return HANDLER_FINISHED;
41473                 }
41474         }
41475 -       
41476 +
41477         if (revents & FDEVENT_OUT) {
41478                 if (hctx->state == FCGI_STATE_CONNECT_DELAYED ||
41479                     hctx->state == FCGI_STATE_WRITE) {
41480                         /* we are allowed to send something out
41481 -                        * 
41482 +                        *
41483                          * 1. in a unfinished connect() call
41484                          * 2. in a unfinished write() call (long POST request)
41485                          */
41486                         return mod_fastcgi_handle_subrequest(srv, con, p);
41487                 } else {
41488 -                       log_error_write(srv, __FILE__, __LINE__, "sd", 
41489 -                                       "got a FDEVENT_OUT and didn't know why:", 
41490 +                       log_error_write(srv, __FILE__, __LINE__, "sd",
41491 +                                       "got a FDEVENT_OUT and didn't know why:",
41492                                         hctx->state);
41493                 }
41494         }
41495 -       
41496 +
41497         /* perhaps this issue is already handled */
41498         if (revents & FDEVENT_HUP) {
41499                 if (hctx->state == FCGI_STATE_CONNECT_DELAYED) {
41500                         /* getoptsock will catch this one (right ?)
41501 -                        * 
41502 -                        * if we are in connect we might get a EINPROGRESS 
41503 -                        * in the first call and a FDEVENT_HUP in the 
41504 +                        *
41505 +                        * if we are in connect we might get a EINPROGRESS
41506 +                        * in the first call and a FDEVENT_HUP in the
41507                          * second round
41508 -                        * 
41509 +                        *
41510                          * FIXME: as it is a bit ugly.
41511 -                        * 
41512 +                        *
41513                          */
41514                         return mod_fastcgi_handle_subrequest(srv, con, p);
41515                 } else if (hctx->state == FCGI_STATE_READ &&
41516                            hctx->proc->port == 0) {
41517                         /* FIXME:
41518 -                        * 
41519 +                        *
41520                          * ioctl says 8192 bytes to read from PHP and we receive directly a HUP for the socket
41521                          * even if the FCGI_FIN packet is not received yet
41522                          */
41523                 } else {
41524 -                       log_error_write(srv, __FILE__, __LINE__, "sbSBSDSd", 
41525 -                                       "error: unexpected close of fastcgi connection for", 
41526 +                       log_error_write(srv, __FILE__, __LINE__, "sbSBSDSd",
41527 +                                       "error: unexpected close of fastcgi connection for",
41528                                         con->uri.path,
41529 -                                       "(no fastcgi process on host:", 
41530 +                                       "(no fastcgi process on host:",
41531                                         host->host,
41532 -                                       ", port: ", 
41533 +                                       ", port: ",
41534                                         host->port,
41535                                         " ?)",
41536                                         hctx->state);
41537 -                       
41538 +
41539                         connection_set_state(srv, con, CON_STATE_ERROR);
41540                         fcgi_connection_close(srv, hctx);
41541                         joblist_append(srv, con);
41542                 }
41543         } else if (revents & FDEVENT_ERR) {
41544 -               log_error_write(srv, __FILE__, __LINE__, "s", 
41545 +               log_error_write(srv, __FILE__, __LINE__, "s",
41546                                 "fcgi: got a FDEVENT_ERR. Don't know why.");
41547                 /* kill all connections to the fastcgi process */
41548  
41549 @@ -3304,46 +3219,43 @@
41550                 fcgi_connection_close(srv, hctx);
41551                 joblist_append(srv, con);
41552         }
41553 -       
41554 +
41555         return HANDLER_FINISHED;
41556  }
41557 -#define PATCH(x) \
41558 -       p->conf.x = s->x;
41559 +
41560  static int fcgi_patch_connection(server *srv, connection *con, plugin_data *p) {
41561         size_t i, j;
41562         plugin_config *s = p->config_storage[0];
41563 -       
41564 -       PATCH(exts);
41565 -       PATCH(debug);
41566 -       PATCH(ext_mapping);
41567 -       
41568 +
41569 +       PATCH_OPTION(exts);
41570 +       PATCH_OPTION(debug);
41571 +       PATCH_OPTION(ext_mapping);
41572 +
41573         /* skip the first, the global context */
41574         for (i = 1; i < srv->config_context->used; i++) {
41575                 data_config *dc = (data_config *)srv->config_context->data[i];
41576                 s = p->config_storage[i];
41577 -               
41578 +
41579                 /* condition didn't match */
41580                 if (!config_check_cond(srv, con, dc)) continue;
41581 -               
41582 +
41583                 /* merge config */
41584                 for (j = 0; j < dc->value->used; j++) {
41585                         data_unset *du = dc->value->data[j];
41586 -                       
41587 +
41588                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("fastcgi.server"))) {
41589 -                               PATCH(exts);
41590 +                               PATCH_OPTION(exts);
41591                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("fastcgi.debug"))) {
41592 -                               PATCH(debug);
41593 +                               PATCH_OPTION(debug);
41594                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("fastcgi.map-extensions"))) {
41595 -                               PATCH(ext_mapping);
41596 +                               PATCH_OPTION(ext_mapping);
41597                         }
41598                 }
41599         }
41600 -       
41601 +
41602         return 0;
41603  }
41604 -#undef PATCH
41605  
41606 -
41607  static handler_t fcgi_check_extension(server *srv, connection *con, void *p_d, int uri_path_handler) {
41608         plugin_data *p = p_d;
41609         size_t s_len;
41610 @@ -3351,16 +3263,16 @@
41611         buffer *fn;
41612         fcgi_extension *extension = NULL;
41613         fcgi_extension_host *host = NULL;
41614 -       
41615 +
41616         /* Possibly, we processed already this request */
41617         if (con->file_started == 1) return HANDLER_GO_ON;
41618  
41619         fn = uri_path_handler ? con->uri.path : con->physical.path;
41620  
41621         if (buffer_is_empty(fn)) return HANDLER_GO_ON;
41622 -       
41623 +
41624         s_len = fn->used - 1;
41625 -       
41626 +
41627         fcgi_patch_connection(srv, con, p);
41628  
41629         /* fastcgi.map-extensions maps extensions to existing fastcgi.server entries
41630 @@ -3368,24 +3280,24 @@
41631          * fastcgi.map-extensions = ( ".php3" => ".php" )
41632          *
41633          * fastcgi.server = ( ".php" => ... )
41634 -        * 
41635 +        *
41636          * */
41637  
41638         /* check if extension-mapping matches */
41639         for (k = 0; k < p->conf.ext_mapping->used; k++) {
41640                 data_string *ds = (data_string *)p->conf.ext_mapping->data[k];
41641                 size_t ct_len; /* length of the config entry */
41642 -               
41643 +
41644                 if (ds->key->used == 0) continue;
41645 -               
41646 +
41647                 ct_len = ds->key->used - 1;
41648 -               
41649 +
41650                 if (s_len < ct_len) continue;
41651 -               
41652 +
41653                 /* found a mapping */
41654                 if (0 == strncmp(fn->ptr + s_len - ct_len, ds->key->ptr, ct_len)) {
41655                         /* check if we know the extension */
41656 -                       
41657 +
41658                         /* we can reuse k here */
41659                         for (k = 0; k < p->conf.exts->used; k++) {
41660                                 extension = p->conf.exts->exts[k];
41661 @@ -3407,15 +3319,15 @@
41662                 /* check if extension matches */
41663                 for (k = 0; k < p->conf.exts->used; k++) {
41664                         size_t ct_len; /* length of the config entry */
41665 -               
41666 +
41667                         extension = p->conf.exts->exts[k];
41668 -               
41669 +
41670                         if (extension->key->used == 0) continue;
41671 -               
41672 +
41673                         ct_len = extension->key->used - 1;
41674 -               
41675 +
41676                         if (s_len < ct_len) continue;
41677 -               
41678 +
41679                         /* check extension in the form "/fcgi_pattern" */
41680                         if (*(extension->key->ptr) == '/' && strncmp(fn->ptr, extension->key->ptr, ct_len) == 0) {
41681                                 break;
41682 @@ -3441,10 +3353,10 @@
41683                         continue;
41684                 }
41685  
41686 -               /* we found one host that is alive */ 
41687 +               /* we found one host that is alive */
41688                 break;
41689         }
41690 -       
41691 +
41692         if (!host) {
41693                 /* sorry, we don't have a server alive for this ext */
41694                 buffer_reset(con->physical.path);
41695 @@ -3459,72 +3371,72 @@
41696                                         "on", extension->key,
41697                                         "are down.");
41698                 }
41699 -               
41700 +
41701                 return HANDLER_FINISHED;
41702         }
41703  
41704         /* a note about no handler is not sent yey */
41705         extension->note_is_sent = 0;
41706  
41707 -       /* 
41708 -        * if check-local is disabled, use the uri.path handler 
41709 -        * 
41710 +       /*
41711 +        * if check-local is disabled, use the uri.path handler
41712 +        *
41713          */
41714 -       
41715 +
41716         /* init handler-context */
41717         if (uri_path_handler) {
41718                 if (host->check_local == 0) {
41719                         handler_ctx *hctx;
41720                         char *pathinfo;
41721 -                       
41722 +
41723                         hctx = handler_ctx_init();
41724 -                       
41725 +
41726                         hctx->remote_conn      = con;
41727                         hctx->plugin_data      = p;
41728                         hctx->proc             = NULL;
41729                         hctx->ext              = extension;
41730 -       
41731  
41732 +
41733                         hctx->conf.exts        = p->conf.exts;
41734                         hctx->conf.debug       = p->conf.debug;
41735 -                               
41736 +
41737                         con->plugin_ctx[p->id] = hctx;
41738 -                               
41739 +
41740                         con->mode = p->id;
41741 -                               
41742 +
41743                         if (con->conf.log_request_handling) {
41744 -                               log_error_write(srv, __FILE__, __LINE__, "s", 
41745 +                               log_error_write(srv, __FILE__, __LINE__, "s",
41746                                 "handling it in mod_fastcgi");
41747                         }
41748 -                               
41749 -                       /* the prefix is the SCRIPT_NAME, 
41750 +
41751 +                       /* the prefix is the SCRIPT_NAME,
41752                          * everthing from start to the next slash
41753                          * this is important for check-local = "disable"
41754 -                        * 
41755 +                        *
41756                          * if prefix = /admin.fcgi
41757 -                        * 
41758 +                        *
41759                          * /admin.fcgi/foo/bar
41760 -                        * 
41761 +                        *
41762                          * SCRIPT_NAME = /admin.fcgi
41763                          * PATH_INFO   = /foo/bar
41764 -                        * 
41765 +                        *
41766                          * if prefix = /fcgi-bin/
41767 -                        * 
41768 +                        *
41769                          * /fcgi-bin/foo/bar
41770 -                        * 
41771 +                        *
41772                          * SCRIPT_NAME = /fcgi-bin/foo
41773                          * PATH_INFO   = /bar
41774 -                        * 
41775 +                        *
41776                          */
41777 -                       
41778 +
41779                         /* the rewrite is only done for /prefix/? matches */
41780                         if (extension->key->ptr[0] == '/' &&
41781                             con->uri.path->used > extension->key->used &&
41782                             NULL != (pathinfo = strchr(con->uri.path->ptr + extension->key->used - 1, '/'))) {
41783 -                               /* rewrite uri.path and pathinfo */ 
41784 -                               
41785 +                               /* rewrite uri.path and pathinfo */
41786 +
41787                                 buffer_copy_string(con->request.pathinfo, pathinfo);
41788 -                               
41789 +
41790                                 con->uri.path->used -= con->request.pathinfo->used - 1;
41791                                 con->uri.path->ptr[con->uri.path->used - 1] = '\0';
41792                         }
41793 @@ -3532,19 +3444,19 @@
41794         } else {
41795                 handler_ctx *hctx;
41796                 hctx = handler_ctx_init();
41797 -               
41798 +
41799                 hctx->remote_conn      = con;
41800                 hctx->plugin_data      = p;
41801                 hctx->proc             = NULL;
41802                 hctx->ext              = extension;
41803 -               
41804 +
41805                 hctx->conf.exts        = p->conf.exts;
41806                 hctx->conf.debug       = p->conf.debug;
41807 -               
41808 +
41809                 con->plugin_ctx[p->id] = hctx;
41810 -               
41811 +
41812                 con->mode = p->id;
41813 -               
41814 +
41815                 if (con->conf.log_request_handling) {
41816                         log_error_write(srv, __FILE__, __LINE__, "s", "handling it in mod_fastcgi");
41817                 }
41818 @@ -3566,19 +3478,19 @@
41819  JOBLIST_FUNC(mod_fastcgi_handle_joblist) {
41820         plugin_data *p = p_d;
41821         handler_ctx *hctx = con->plugin_ctx[p->id];
41822 -       
41823 +
41824         if (hctx == NULL) return HANDLER_GO_ON;
41825  
41826         if (hctx->fd != -1) {
41827                 switch (hctx->state) {
41828                 case FCGI_STATE_READ:
41829                         fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);
41830 -                       
41831 +
41832                         break;
41833                 case FCGI_STATE_CONNECT_DELAYED:
41834                 case FCGI_STATE_WRITE:
41835                         fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
41836 -                       
41837 +
41838                         break;
41839                 case FCGI_STATE_INIT:
41840                         /* at reconnect */
41841 @@ -3595,7 +3507,7 @@
41842  
41843  static handler_t fcgi_connection_close_callback(server *srv, connection *con, void *p_d) {
41844         plugin_data *p = p_d;
41845 -       
41846 +
41847         fcgi_connection_close(srv, con->plugin_ctx[p->id]);
41848  
41849         return HANDLER_GO_ON;
41850 @@ -3604,16 +3516,39 @@
41851  TRIGGER_FUNC(mod_fastcgi_handle_trigger) {
41852         plugin_data *p = p_d;
41853         size_t i, j, n;
41854 -       
41855 -       
41856 +
41857 +
41858         /* perhaps we should kill a connect attempt after 10-15 seconds
41859 -        * 
41860 +        *
41861          * currently we wait for the TCP timeout which is on Linux 180 seconds
41862 -        * 
41863 -        * 
41864 -        * 
41865 +        *
41866          */
41867  
41868 +       for (i = 0; i < srv->conns->used; i++) {
41869 +               connection *con = srv->conns->ptr[i];
41870 +               handler_ctx *hctx = con->plugin_ctx[p->id];
41871 +
41872 +               /* if a connection is ours and is in handle-req for more than max-request-time
41873 +                * kill the connection */
41874 +
41875 +               if (con->mode != p->id) continue;
41876 +               if (con->state != CON_STATE_HANDLE_REQUEST) continue;
41877 +               if (srv->cur_ts < con->request_start + 60) continue;
41878 +
41879 +               /* the request is waiting for a FCGI_STDOUT since 60 seconds */
41880 +
41881 +               /* kill the connection */
41882 +
41883 +               log_error_write(srv, __FILE__, __LINE__, "s", "fastcgi backend didn't responded after 60 seconds");
41884 +
41885 +               fcgi_connection_close(srv, hctx);
41886 +
41887 +               con->mode = DIRECT;
41888 +               con->http_status = 500;
41889 +
41890 +               joblist_append(srv, con);
41891 +       }
41892 +
41893         /* check all childs if they are still up */
41894  
41895         for (i = 0; i < srv->config_context->used; i++) {
41896 @@ -3628,45 +3563,45 @@
41897                         fcgi_extension *ex;
41898  
41899                         ex = exts->exts[j];
41900 -                       
41901 +
41902                         for (n = 0; n < ex->used; n++) {
41903 -                               
41904 +
41905                                 fcgi_proc *proc;
41906                                 unsigned long sum_load = 0;
41907                                 fcgi_extension_host *host;
41908 -                               
41909 +
41910                                 host = ex->hosts[n];
41911 -                               
41912 +
41913                                 fcgi_restart_dead_procs(srv, p, host);
41914 -                               
41915 +
41916                                 for (proc = host->first; proc; proc = proc->next) {
41917                                         sum_load += proc->load;
41918                                 }
41919 -                               
41920 +
41921                                 if (host->num_procs &&
41922                                     host->num_procs < host->max_procs &&
41923                                     (sum_load / host->num_procs) > host->max_load_per_proc) {
41924                                         /* overload, spawn new child */
41925                                         if (p->conf.debug) {
41926 -                                               log_error_write(srv, __FILE__, __LINE__, "s", 
41927 +                                               log_error_write(srv, __FILE__, __LINE__, "s",
41928                                                                 "overload detected, spawning a new child");
41929                                         }
41930 -                                       
41931 +
41932                                         for (proc = host->unused_procs; proc && proc->pid != 0; proc = proc->next);
41933 -                                       
41934 +
41935                                         if (proc) {
41936                                                 if (proc == host->unused_procs) host->unused_procs = proc->next;
41937 -                                               
41938 +
41939                                                 if (proc->next) proc->next->prev = NULL;
41940 -                                               
41941 +
41942                                                 host->max_id++;
41943                                         } else {
41944                                                 proc = fastcgi_process_init();
41945                                                 proc->id = host->max_id++;
41946                                         }
41947 -                                       
41948 +
41949                                         host->num_procs++;
41950 -                                       
41951 +
41952                                         if (buffer_is_empty(host->unixsocket)) {
41953                                                 proc->port = host->port + proc->id;
41954                                         } else {
41955 @@ -3674,13 +3609,13 @@
41956                                                 buffer_append_string(proc->unixsocket, "-");
41957                                                 buffer_append_long(proc->unixsocket, proc->id);
41958                                         }
41959 -                                       
41960 +
41961                                         if (fcgi_spawn_connection(srv, p, host, proc)) {
41962                                                 log_error_write(srv, __FILE__, __LINE__, "s",
41963                                                                 "ERROR: spawning fcgi failed.");
41964                                                 return HANDLER_ERROR;
41965                                         }
41966 -                                       
41967 +
41968                                         proc->prev = NULL;
41969                                         proc->next = host->first;
41970                                         if (host->first) {
41971 @@ -3688,56 +3623,56 @@
41972                                         }
41973                                         host->first = proc;
41974                                 }
41975 -                               
41976 +
41977                                 for (proc = host->first; proc; proc = proc->next) {
41978                                         if (proc->load != 0) break;
41979                                         if (host->num_procs <= host->min_procs) break;
41980                                         if (proc->pid == 0) continue;
41981 -                                       
41982 +
41983                                         if (srv->cur_ts - proc->last_used > host->idle_timeout) {
41984                                                 /* a proc is idling for a long time now,
41985                                                  * terminated it */
41986 -                                               
41987 +
41988                                                 if (p->conf.debug) {
41989 -                                                       log_error_write(srv, __FILE__, __LINE__, "ssbsd", 
41990 -                                                                       "idle-timeout reached, terminating child:", 
41991 -                                                                       "socket:", proc->connection_name, 
41992 +                                                       log_error_write(srv, __FILE__, __LINE__, "ssbsd",
41993 +                                                                       "idle-timeout reached, terminating child:",
41994 +                                                                       "socket:", proc->connection_name,
41995                                                                         "pid", proc->pid);
41996                                                 }
41997 -                                               
41998 -                                               
41999 +
42000 +
42001                                                 if (proc->next) proc->next->prev = proc->prev;
42002                                                 if (proc->prev) proc->prev->next = proc->next;
42003 -                                               
42004 +
42005                                                 if (proc->prev == NULL) host->first = proc->next;
42006 -                                               
42007 +
42008                                                 proc->prev = NULL;
42009                                                 proc->next = host->unused_procs;
42010 -                                               
42011 +
42012                                                 if (host->unused_procs) host->unused_procs->prev = proc;
42013                                                 host->unused_procs = proc;
42014 -                                               
42015 +
42016                                                 kill(proc->pid, SIGTERM);
42017 -                                               
42018 +
42019                                                 proc->state = PROC_STATE_KILLED;
42020 -                                               
42021 -                                               log_error_write(srv, __FILE__, __LINE__, "ssbsd", 
42022 -                                                                       "killed:", 
42023 -                                                                       "socket:", proc->connection_name, 
42024 +
42025 +                                               log_error_write(srv, __FILE__, __LINE__, "ssbsd",
42026 +                                                                       "killed:",
42027 +                                                                       "socket:", proc->connection_name,
42028                                                                         "pid", proc->pid);
42029 -                                               
42030 +
42031                                                 host->num_procs--;
42032 -                                               
42033 +
42034                                                 /* proc is now in unused, let the next second handle the next process */
42035                                                 break;
42036 -                                       }       
42037 +                                       }
42038                                 }
42039 -                               
42040 +
42041                                 for (proc = host->unused_procs; proc; proc = proc->next) {
42042                                         int status;
42043 -                                       
42044 +
42045                                         if (proc->pid == 0) continue;
42046 -                                       
42047 +#ifndef _WIN32
42048                                         switch (waitpid(proc->pid, &status, WNOHANG)) {
42049                                         case 0:
42050                                                 /* child still running after timeout, good */
42051 @@ -3745,10 +3680,10 @@
42052                                         case -1:
42053                                                 if (errno != EINTR) {
42054                                                         /* no PID found ? should never happen */
42055 -                                                       log_error_write(srv, __FILE__, __LINE__, "sddss", 
42056 +                                                       log_error_write(srv, __FILE__, __LINE__, "sddss",
42057                                                                         "pid ", proc->pid, proc->state,
42058                                                                         "not found:", strerror(errno));
42059 -                                                       
42060 +
42061  #if 0
42062                                                         if (errno == ECHILD) {
42063                                                                 /* someone else has cleaned up for us */
42064 @@ -3762,25 +3697,26 @@
42065                                                 /* the child should not terminate at all */
42066                                                 if (WIFEXITED(status)) {
42067                                                         if (proc->state != PROC_STATE_KILLED) {
42068 -                                                               log_error_write(srv, __FILE__, __LINE__, "sdb", 
42069 -                                                                               "child exited:", 
42070 +                                                               log_error_write(srv, __FILE__, __LINE__, "sdb",
42071 +                                                                               "child exited:",
42072                                                                                 WEXITSTATUS(status), proc->connection_name);
42073                                                         }
42074                                                 } else if (WIFSIGNALED(status)) {
42075                                                         if (WTERMSIG(status) != SIGTERM) {
42076 -                                                               log_error_write(srv, __FILE__, __LINE__, "sd", 
42077 -                                                                               "child signaled:", 
42078 +                                                               log_error_write(srv, __FILE__, __LINE__, "sd",
42079 +                                                                               "child signaled:",
42080                                                                                 WTERMSIG(status));
42081                                                         }
42082                                                 } else {
42083 -                                                       log_error_write(srv, __FILE__, __LINE__, "sd", 
42084 -                                                                       "child died somehow:", 
42085 +                                                       log_error_write(srv, __FILE__, __LINE__, "sd",
42086 +                                                                       "child died somehow:",
42087                                                                         status);
42088                                                 }
42089                                                 proc->pid = 0;
42090                                                 proc->state = PROC_STATE_UNSET;
42091                                                 host->max_id--;
42092                                         }
42093 +#endif
42094                                 }
42095                         }
42096                 }
42097 @@ -3804,8 +3740,8 @@
42098         p->handle_subrequest       = mod_fastcgi_handle_subrequest;
42099         p->handle_joblist          = mod_fastcgi_handle_joblist;
42100         p->handle_trigger          = mod_fastcgi_handle_trigger;
42101 -       
42102 +
42103         p->data         = NULL;
42104 -       
42105 +
42106         return 0;
42107  }
42108
42109 Property changes on: src/mod_fastcgi.c
42110 ___________________________________________________________________
42111 Name: svn:eol-style
42112    + native
42113
42114 Index: src/fdevent_poll.c
42115 ===================================================================
42116 --- src/fdevent_poll.c  (.../tags/lighttpd-1.4.11)      (revision 1159)
42117 +++ src/fdevent_poll.c  (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
42118 @@ -1,6 +1,5 @@
42119  #include <sys/types.h>
42120  
42121 -#include <unistd.h>
42122  #include <stdlib.h>
42123  #include <stdio.h>
42124  #include <string.h>
42125 @@ -20,19 +19,19 @@
42126  
42127  static int fdevent_poll_event_del(fdevents *ev, int fde_ndx, int fd) {
42128         if (fde_ndx < 0) return -1;
42129 -       
42130 +
42131         if ((size_t)fde_ndx >= ev->used) {
42132                 fprintf(stderr, "%s.%d: del! out of range %d %zd\n", __FILE__, __LINE__, fde_ndx, ev->used);
42133                 SEGFAULT();
42134         }
42135 -       
42136 +
42137         if (ev->pollfds[fde_ndx].fd == fd) {
42138                 size_t k = fde_ndx;
42139 -               
42140 +
42141                 ev->pollfds[k].fd = -1;
42142                 /* ev->pollfds[k].events = 0; */
42143                 /* ev->pollfds[k].revents = 0; */
42144 -               
42145 +
42146                 if (ev->unused.size == 0) {
42147                         ev->unused.size = 16;
42148                         ev->unused.ptr = malloc(sizeof(*(ev->unused.ptr)) * ev->unused.size);
42149 @@ -40,47 +39,47 @@
42150                         ev->unused.size += 16;
42151                         ev->unused.ptr = realloc(ev->unused.ptr, sizeof(*(ev->unused.ptr)) * ev->unused.size);
42152                 }
42153 -               
42154 +
42155                 ev->unused.ptr[ev->unused.used++] = k;
42156         } else {
42157                 SEGFAULT();
42158         }
42159 -       
42160 +
42161         return -1;
42162  }
42163  
42164  #if 0
42165  static int fdevent_poll_event_compress(fdevents *ev) {
42166         size_t j;
42167 -       
42168 +
42169         if (ev->used == 0) return 0;
42170         if (ev->unused.used != 0) return 0;
42171 -       
42172 +
42173         for (j = ev->used - 1; j + 1 > 0 && ev->pollfds[j].fd == -1; j--) ev->used--;
42174 -       
42175 +
42176         return 0;
42177  }
42178  #endif
42179  
42180  static int fdevent_poll_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
42181         /* known index */
42182 -       
42183 +
42184         if (fde_ndx != -1) {
42185                 if (ev->pollfds[fde_ndx].fd == fd) {
42186                         ev->pollfds[fde_ndx].events = events;
42187 -                       
42188 +
42189                         return fde_ndx;
42190                 }
42191                 fprintf(stderr, "%s.%d: add: (%d, %d)\n", __FILE__, __LINE__, fde_ndx, ev->pollfds[fde_ndx].fd);
42192                 SEGFAULT();
42193         }
42194 -       
42195 +
42196         if (ev->unused.used > 0) {
42197                 int k = ev->unused.ptr[--ev->unused.used];
42198 -               
42199 +
42200                 ev->pollfds[k].fd = fd;
42201                 ev->pollfds[k].events = events;
42202 -               
42203 +
42204                 return k;
42205         } else {
42206                 if (ev->size == 0) {
42207 @@ -90,10 +89,10 @@
42208                         ev->size += 16;
42209                         ev->pollfds = realloc(ev->pollfds, sizeof(*ev->pollfds) * ev->size);
42210                 }
42211 -               
42212 +
42213                 ev->pollfds[ev->used].fd = fd;
42214                 ev->pollfds[ev->used].events = events;
42215 -               
42216 +
42217                 return ev->used++;
42218         }
42219  }
42220 @@ -109,12 +108,12 @@
42221         int r, poll_r;
42222         if (ndx >= ev->used) {
42223                 fprintf(stderr, "%s.%d: dying because: event: %zd >= %zd\n", __FILE__, __LINE__, ndx, ev->used);
42224 -               
42225 +
42226                 SEGFAULT();
42227 -               
42228 +
42229                 return 0;
42230         }
42231 -       
42232 +
42233         if (ev->pollfds[ndx].revents & POLLNVAL) {
42234                 /* should never happen */
42235                 SEGFAULT();
42236 @@ -131,7 +130,7 @@
42237         if (poll_r & POLLHUP) r |= FDEVENT_HUP;
42238         if (poll_r & POLLNVAL) r |= FDEVENT_NVAL;
42239         if (poll_r & POLLPRI) r |= FDEVENT_PRI;
42240 -       
42241 +
42242         return ev->pollfds[ndx].revents;
42243  }
42244  
42245 @@ -141,12 +140,12 @@
42246  
42247  static int fdevent_poll_event_next_fdndx(fdevents *ev, int ndx) {
42248         size_t i;
42249 -       
42250 +
42251         i = (ndx < 0) ? 0 : ndx + 1;
42252         for (; i < ev->used; i++) {
42253                 if (ev->pollfds[i].revents) break;
42254         }
42255 -       
42256 +
42257         return i;
42258  }
42259  
42260 @@ -154,17 +153,17 @@
42261         ev->type = FDEVENT_HANDLER_POLL;
42262  #define SET(x) \
42263         ev->x = fdevent_poll_##x;
42264 -       
42265 +
42266         SET(free);
42267         SET(poll);
42268 -       
42269 +
42270         SET(event_del);
42271         SET(event_add);
42272 -       
42273 +
42274         SET(event_next_fdndx);
42275         SET(event_get_fd);
42276         SET(event_get_revent);
42277 -       
42278 +
42279         return 0;
42280  }
42281  
42282
42283 Property changes on: src/fdevent_poll.c
42284 ___________________________________________________________________
42285 Name: svn:eol-style
42286    + native
42287
42288 Index: src/network_solaris_sendfilev.c
42289 ===================================================================
42290 --- src/network_solaris_sendfilev.c     (.../tags/lighttpd-1.4.11)      (revision 1159)
42291 +++ src/network_solaris_sendfilev.c     (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
42292 @@ -29,114 +29,34 @@
42293  #endif
42294  
42295  /**
42296 - * a very simple sendfilev() interface for solaris which can be optimised a lot more 
42297 + * a very simple sendfilev() interface for solaris which can be optimised a lot more
42298   * as solaris sendfilev() supports 'sending everythin in one syscall()'
42299 - * 
42300 - * If you want such an interface and need the performance, just give me an account on 
42301 - * a solaris box. 
42302 + *
42303 + * If you want such an interface and need the performance, just give me an account on
42304 + * a solaris box.
42305   *   - jan@kneschke.de
42306   */
42307  
42308  
42309 -int network_write_chunkqueue_solarissendfilev(server *srv, connection *con, int fd, chunkqueue *cq) {
42310 +NETWORK_BACKEND_WRITE(solarissendfilev) {
42311         chunk *c;
42312         size_t chunks_written = 0;
42313 -       
42314 +
42315         for(c = cq->first; c; c = c->next, chunks_written++) {
42316                 int chunk_finished = 0;
42317 -               
42318 +               network_status_t ret;
42319 +
42320                 switch(c->type) {
42321 -               case MEM_CHUNK: {
42322 -                       char * offset;
42323 -                       size_t toSend;
42324 -                       ssize_t r;
42325 -                       
42326 -                       size_t num_chunks, i;
42327 -                       struct iovec chunks[UIO_MAXIOV];
42328 -                       chunk *tc;
42329 -                       
42330 -                       size_t num_bytes = 0;
42331 -                       
42332 -                       /* we can't send more then SSIZE_MAX bytes in one chunk */
42333 -                       
42334 -                       /* build writev list 
42335 -                        * 
42336 -                        * 1. limit: num_chunks < UIO_MAXIOV
42337 -                        * 2. limit: num_bytes < SSIZE_MAX
42338 -                        */
42339 -                       for(num_chunks = 0, tc = c; tc && tc->type == MEM_CHUNK && num_chunks < UIO_MAXIOV; num_chunks++, tc = tc->next);
42340 -                       
42341 -                       for(tc = c, i = 0; i < num_chunks; tc = tc->next, i++) {
42342 -                               if (tc->mem->used == 0) {
42343 -                                       chunks[i].iov_base = tc->mem->ptr;
42344 -                                       chunks[i].iov_len  = 0;
42345 -                               } else {
42346 -                                       offset = tc->mem->ptr + tc->offset;
42347 -                                       toSend = tc->mem->used - 1 - tc->offset;
42348 -                               
42349 -                                       chunks[i].iov_base = offset;
42350 -                                       
42351 -                                       /* protect the return value of writev() */
42352 -                                       if (toSend > SSIZE_MAX ||
42353 -                                           num_bytes + toSend > SSIZE_MAX) {
42354 -                                               chunks[i].iov_len = SSIZE_MAX - num_bytes;
42355 -                                               
42356 -                                               num_chunks = i + 1;
42357 -                                               break;
42358 -                                       } else {
42359 -                                               chunks[i].iov_len = toSend;
42360 -                                       }
42361 -                                       
42362 -                                       num_bytes += toSend;
42363 -                               }
42364 +               case MEM_CHUNK:
42365 +                       ret = network_write_chunkqueue_writev_mem(srv, con, fd, cq, &c);
42366 +
42367 +                       if (ret != NETWORK_STATUS_SUCCESS) {
42368 +                               return ret;
42369                         }
42370 -                       
42371 -                       if ((r = writev(fd, chunks, num_chunks)) < 0) {
42372 -                               switch (errno) {
42373 -                               case EAGAIN:
42374 -                               case EINTR:
42375 -                                       r = 0;
42376 -                                       break;
42377 -                               case EPIPE:
42378 -                               case ECONNRESET:
42379 -                                       return -2;
42380 -                               default:
42381 -                                       log_error_write(srv, __FILE__, __LINE__, "ssd", 
42382 -                                                       "writev failed:", strerror(errno), fd);
42383 -                               
42384 -                                       return -1;
42385 -                               }
42386 -                       }
42387 -                       
42388 -                       /* check which chunks have been written */
42389 -                       cq->bytes_out += r;
42390 -                       
42391 -                       for(i = 0, tc = c; i < num_chunks; i++, tc = tc->next) {
42392 -                               if (r >= (ssize_t)chunks[i].iov_len) {
42393 -                                       /* written */
42394 -                                       r -= chunks[i].iov_len;
42395 -                                       tc->offset += chunks[i].iov_len;
42396 -                                       
42397 -                                       if (chunk_finished) {
42398 -                                               /* skip the chunks from further touches */
42399 -                                               chunks_written++;
42400 -                                               c = c->next;
42401 -                                       } else {
42402 -                                               /* chunks_written + c = c->next is done in the for()*/
42403 -                                               chunk_finished++;
42404 -                                       }
42405 -                               } else {
42406 -                                       /* partially written */
42407 -                                       
42408 -                                       tc->offset += r;
42409 -                                       chunk_finished = 0;
42410 -                                       
42411 -                                       break;
42412 -                               }
42413 -                       }
42414 -                       
42415 +
42416 +                       chunk_finished = 1;
42417 +
42418                         break;
42419 -               }
42420                 case FILE_CHUNK: {
42421                         ssize_t r;
42422                         off_t offset;
42423 @@ -144,25 +64,25 @@
42424                         sendfilevec_t fvec;
42425                         stat_cache_entry *sce = NULL;
42426                         int ifd;
42427 -                       
42428 +
42429                         if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) {
42430                                 log_error_write(srv, __FILE__, __LINE__, "sb",
42431                                                 strerror(errno), c->file.name);
42432                                 return -1;
42433                         }
42434 -                                       
42435 +
42436                         offset = c->file.start + c->offset;
42437                         toSend = c->file.length - c->offset;
42438 -                       
42439 +
42440                         if (offset > sce->st.st_size) {
42441                                 log_error_write(srv, __FILE__, __LINE__, "sb", "file was shrinked:", c->file.name);
42442 -                               
42443 +
42444                                 return -1;
42445                         }
42446  
42447                         if (-1 == (ifd = open(c->file.name->ptr, O_RDONLY))) {
42448                                 log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
42449 -                               
42450 +
42451                                 return -1;
42452                         }
42453  
42454 @@ -170,44 +90,43 @@
42455                         fvec.sfv_flag = 0;
42456                         fvec.sfv_off = offset;
42457                         fvec.sfv_len = toSend;
42458 -                       
42459 +
42460                         /* Solaris sendfilev() */
42461                         if (-1 == (r = sendfilev(fd, &fvec, 1, &written))) {
42462                                 if (errno != EAGAIN) {
42463                                         log_error_write(srv, __FILE__, __LINE__, "ssd", "sendfile: ", strerror(errno), errno);
42464 -                                       
42465 +
42466                                         close(ifd);
42467 -                                       return -1;
42468 +                                       return NETWORK_STATUS_FATAL_ERROR;
42469                                 }
42470 -                               
42471 +
42472                                 r = 0;
42473                         }
42474 -                       
42475 +
42476                         close(ifd);
42477                         c->offset += written;
42478                         cq->bytes_out += written;
42479 -                       
42480 +
42481                         if (c->offset == c->file.length) {
42482                                 chunk_finished = 1;
42483                         }
42484 -                       
42485 +
42486                         break;
42487                 }
42488                 default:
42489 -                       
42490                         log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
42491 -                       
42492 -                       return -1;
42493 +
42494 +                       return NETWORK_STATUS_FATAL_ERROR;
42495                 }
42496 -               
42497 +
42498                 if (!chunk_finished) {
42499                         /* not finished yet */
42500 -                       
42501 +
42502                         break;
42503                 }
42504         }
42505  
42506 -       return chunks_written;
42507 +       return NETWORK_STATUS_SUCCESS;
42508  }
42509  
42510  #endif
42511
42512 Property changes on: src/network_solaris_sendfilev.c
42513 ___________________________________________________________________
42514 Name: svn:eol-style
42515    + native
42516
42517 Index: src/fdevent_select.c
42518 ===================================================================
42519 --- src/fdevent_select.c        (.../tags/lighttpd-1.4.11)      (revision 1159)
42520 +++ src/fdevent_select.c        (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
42521 @@ -1,18 +1,19 @@
42522 -#include <sys/time.h>
42523  #include <sys/types.h>
42524  
42525 -#include <unistd.h>
42526  #include <stdlib.h>
42527  #include <string.h>
42528  #include <errno.h>
42529  #include <signal.h>
42530  #include <fcntl.h>
42531  #include <assert.h>
42532 +#include <stdio.h>
42533  
42534  #include "fdevent.h"
42535  #include "settings.h"
42536  #include "buffer.h"
42537  
42538 +#include "sys-socket.h"
42539 +
42540  #ifdef USE_SELECT
42541  
42542  static int fdevent_select_reset(fdevents *ev) {
42543 @@ -38,7 +39,9 @@
42544         UNUSED(fde_ndx);
42545  
42546         /* we should be protected by max-fds, but you never know */
42547 +#ifndef _WIN32
42548         assert(fd < FD_SETSIZE);
42549 +#endif
42550  
42551         if (events & FDEVENT_IN) {
42552                 FD_SET(fd, &(ev->select_set_read));
42553 @@ -49,28 +52,28 @@
42554                 FD_SET(fd, &(ev->select_set_write));
42555         }
42556         FD_SET(fd, &(ev->select_set_error));
42557 -       
42558 +
42559         if (fd > ev->select_max_fd) ev->select_max_fd = fd;
42560 -       
42561 +
42562         return fd;
42563  }
42564  
42565  static int fdevent_select_poll(fdevents *ev, int timeout_ms) {
42566         struct timeval tv;
42567 -       
42568 +
42569         tv.tv_sec =  timeout_ms / 1000;
42570         tv.tv_usec = (timeout_ms % 1000) * 1000;
42571 -       
42572 +
42573         ev->select_read = ev->select_set_read;
42574         ev->select_write = ev->select_set_write;
42575         ev->select_error = ev->select_set_error;
42576 -       
42577 +
42578         return select(ev->select_max_fd + 1, &(ev->select_read), &(ev->select_write), &(ev->select_error), &tv);
42579  }
42580  
42581  static int fdevent_select_event_get_revent(fdevents *ev, size_t ndx) {
42582         int revents = 0;
42583 -       
42584 +
42585         if (FD_ISSET(ndx, &(ev->select_read))) {
42586                 revents |= FDEVENT_IN;
42587         }
42588 @@ -80,7 +83,7 @@
42589         if (FD_ISSET(ndx, &(ev->select_error))) {
42590                 revents |= FDEVENT_ERR;
42591         }
42592 -       
42593 +
42594         return revents;
42595  }
42596  
42597 @@ -92,15 +95,15 @@
42598  
42599  static int fdevent_select_event_next_fdndx(fdevents *ev, int ndx) {
42600         int i;
42601 -       
42602 +
42603         i = (ndx < 0) ? 0 : ndx + 1;
42604 -       
42605 +
42606         for (; i < ev->select_max_fd + 1; i++) {
42607                 if (FD_ISSET(i, &(ev->select_read))) break;
42608                 if (FD_ISSET(i, &(ev->select_write))) break;
42609                 if (FD_ISSET(i, &(ev->select_error))) break;
42610         }
42611 -       
42612 +
42613         return i;
42614  }
42615  
42616 @@ -108,17 +111,17 @@
42617         ev->type = FDEVENT_HANDLER_SELECT;
42618  #define SET(x) \
42619         ev->x = fdevent_select_##x;
42620 -       
42621 +
42622         SET(reset);
42623         SET(poll);
42624 -       
42625 +
42626         SET(event_del);
42627         SET(event_add);
42628 -       
42629 +
42630         SET(event_next_fdndx);
42631         SET(event_get_fd);
42632         SET(event_get_revent);
42633 -       
42634 +
42635         return 0;
42636  }
42637  
42638
42639 Property changes on: src/fdevent_select.c
42640 ___________________________________________________________________
42641 Name: svn:eol-style
42642    + native
42643
42644 Index: src/stream.c
42645 ===================================================================
42646 --- src/stream.c        (.../tags/lighttpd-1.4.11)      (revision 1159)
42647 +++ src/stream.c        (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
42648 @@ -1,7 +1,6 @@
42649  #include <sys/types.h>
42650  #include <sys/stat.h>
42651  
42652 -#include <unistd.h> 
42653  #include <fcntl.h>
42654  
42655  #include "stream.h"
42656 @@ -10,6 +9,7 @@
42657  #endif
42658  
42659  #include "sys-mmap.h"
42660 +#include "sys-files.h"
42661  
42662  #ifndef O_BINARY
42663  # define O_BINARY 0
42664 @@ -19,39 +19,39 @@
42665         struct stat st;
42666  #ifdef HAVE_MMAP
42667         int fd;
42668 -#elif defined __WIN32
42669 +#elif defined _WIN32
42670         HANDLE *fh, *mh;
42671         void *p;
42672  #endif
42673  
42674         f->start = NULL;
42675 -       
42676 +
42677         if (-1 == stat(fn->ptr, &st)) {
42678                 return -1;
42679         }
42680 -       
42681 +
42682         f->size = st.st_size;
42683  
42684  #ifdef HAVE_MMAP
42685         if (-1 == (fd = open(fn->ptr, O_RDONLY | O_BINARY))) {
42686                 return -1;
42687         }
42688 -       
42689 +
42690         f->start = mmap(0, f->size, PROT_READ, MAP_SHARED, fd, 0);
42691 -       
42692 +
42693         close(fd);
42694 -       
42695 +
42696         if (MAP_FAILED == f->start) {
42697                 return -1;
42698         }
42699  
42700 -#elif defined __WIN32
42701 -       fh = CreateFile(fn->ptr, 
42702 -                       GENERIC_READ, 
42703 -                       FILE_SHARE_READ, 
42704 -                       NULL, 
42705 -                       OPEN_EXISTING, 
42706 -                       FILE_ATTRIBUTE_READONLY, 
42707 +#elif defined _WIN32
42708 +       fh = CreateFile(fn->ptr,
42709 +                       GENERIC_READ,
42710 +                       FILE_SHARE_READ,
42711 +                       NULL,
42712 +                       OPEN_EXISTING,
42713 +                       FILE_ATTRIBUTE_READONLY,
42714                         NULL);
42715  
42716         if (!fh) return -1;
42717 @@ -66,7 +66,7 @@
42718         if (!mh) {
42719                 LPVOID lpMsgBuf;
42720                 FormatMessage(
42721 -                       FORMAT_MESSAGE_ALLOCATE_BUFFER | 
42722 +                       FORMAT_MESSAGE_ALLOCATE_BUFFER |
42723                         FORMAT_MESSAGE_FROM_SYSTEM,
42724                         NULL,
42725                         GetLastError(),
42726 @@ -76,7 +76,7 @@
42727  
42728                 return -1;
42729         }
42730 -       
42731 +
42732         p = MapViewOfFile(mh,
42733                         FILE_MAP_READ,
42734                         0,
42735 @@ -87,9 +87,9 @@
42736  
42737         f->start = p;
42738  #else
42739 -# error no mmap found  
42740 +# error no mmap found
42741  #endif
42742 -       
42743 +
42744         return 0;
42745  }
42746  
42747
42748 Property changes on: src/stream.c
42749 ___________________________________________________________________
42750 Name: svn:eol-style
42751    + native
42752
42753
42754 Property changes on: src/mod_ssi_exprparser.y
42755 ___________________________________________________________________
42756 Name: svn:eol-style
42757    + native
42758
42759 Index: src/mod_access.c
42760 ===================================================================
42761 --- src/mod_access.c    (.../tags/lighttpd-1.4.11)      (revision 1159)
42762 +++ src/mod_access.c    (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
42763 @@ -8,126 +8,125 @@
42764  
42765  #include "plugin.h"
42766  
42767 +#include "sys-strings.h"
42768 +
42769  typedef struct {
42770         array *access_deny;
42771  } plugin_config;
42772  
42773  typedef struct {
42774         PLUGIN_DATA;
42775 -       
42776 +
42777         plugin_config **config_storage;
42778 -       
42779 -       plugin_config conf; 
42780 +
42781 +       plugin_config conf;
42782  } plugin_data;
42783  
42784  INIT_FUNC(mod_access_init) {
42785         plugin_data *p;
42786 -       
42787 +
42788         p = calloc(1, sizeof(*p));
42789 -       
42790 +
42791         return p;
42792  }
42793  
42794  FREE_FUNC(mod_access_free) {
42795         plugin_data *p = p_d;
42796 -       
42797 +
42798         UNUSED(srv);
42799  
42800         if (!p) return HANDLER_GO_ON;
42801 -       
42802 +
42803         if (p->config_storage) {
42804                 size_t i;
42805                 for (i = 0; i < srv->config_context->used; i++) {
42806                         plugin_config *s = p->config_storage[i];
42807 -                       
42808 +
42809                         array_free(s->access_deny);
42810 -                       
42811 +
42812                         free(s);
42813                 }
42814                 free(p->config_storage);
42815         }
42816 -       
42817 +
42818         free(p);
42819 -       
42820 +
42821         return HANDLER_GO_ON;
42822  }
42823  
42824  SETDEFAULTS_FUNC(mod_access_set_defaults) {
42825         plugin_data *p = p_d;
42826         size_t i = 0;
42827 -       
42828 -       config_values_t cv[] = { 
42829 +
42830 +       config_values_t cv[] = {
42831                 { "url.access-deny",             NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },
42832                 { NULL,                          NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
42833         };
42834 -       
42835 +
42836         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
42837 -       
42838 +
42839         for (i = 0; i < srv->config_context->used; i++) {
42840                 plugin_config *s;
42841 -               
42842 +
42843                 s = calloc(1, sizeof(plugin_config));
42844                 s->access_deny    = array_init();
42845 -               
42846 +
42847                 cv[0].destination = s->access_deny;
42848 -               
42849 +
42850                 p->config_storage[i] = s;
42851 -       
42852 +
42853                 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
42854                         return HANDLER_ERROR;
42855                 }
42856         }
42857 -       
42858 +
42859         return HANDLER_GO_ON;
42860  }
42861  
42862 -#define PATCH(x) \
42863 -       p->conf.x = s->x;
42864  static int mod_access_patch_connection(server *srv, connection *con, plugin_data *p) {
42865         size_t i, j;
42866         plugin_config *s = p->config_storage[0];
42867  
42868 -       PATCH(access_deny);
42869 -       
42870 +       PATCH_OPTION(access_deny);
42871 +
42872         /* skip the first, the global context */
42873         for (i = 1; i < srv->config_context->used; i++) {
42874                 data_config *dc = (data_config *)srv->config_context->data[i];
42875                 s = p->config_storage[i];
42876 -               
42877 +
42878                 /* condition didn't match */
42879                 if (!config_check_cond(srv, con, dc)) continue;
42880 -               
42881 +
42882                 /* merge config */
42883                 for (j = 0; j < dc->value->used; j++) {
42884                         data_unset *du = dc->value->data[j];
42885 -                       
42886 +
42887                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.access-deny"))) {
42888 -                               PATCH(access_deny);
42889 +                               PATCH_OPTION(access_deny);
42890                         }
42891                 }
42892         }
42893 -       
42894 +
42895         return 0;
42896  }
42897 -#undef PATCH
42898  
42899  URIHANDLER_FUNC(mod_access_uri_handler) {
42900         plugin_data *p = p_d;
42901         int s_len;
42902         size_t k;
42903 -       
42904 +
42905         if (con->uri.path->used == 0) return HANDLER_GO_ON;
42906 -       
42907 +
42908         mod_access_patch_connection(srv, con, p);
42909 -       
42910 +
42911         s_len = con->uri.path->used - 1;
42912 -       
42913 +
42914         for (k = 0; k < p->conf.access_deny->used; k++) {
42915                 data_string *ds = (data_string *)p->conf.access_deny->data[k];
42916                 int ct_len = ds->value->used - 1;
42917 -               
42918 +
42919                 if (ct_len > s_len) continue;
42920 -               
42921 +
42922                 if (ds->value->used == 0) continue;
42923  
42924                 /* if we have a case-insensitive FS we have to lower-case the URI here too */
42925 @@ -135,18 +134,18 @@
42926                 if (con->conf.force_lowercase_filenames) {
42927                         if (0 == strncasecmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) {
42928                                 con->http_status = 403;
42929 -                       
42930 +
42931                                 return HANDLER_FINISHED;
42932                         }
42933                 } else {
42934                         if (0 == strncmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) {
42935                                 con->http_status = 403;
42936 -                       
42937 +
42938                                 return HANDLER_FINISHED;
42939                         }
42940                 }
42941         }
42942 -       
42943 +
42944         /* not found */
42945         return HANDLER_GO_ON;
42946  }
42947 @@ -155,13 +154,13 @@
42948  int mod_access_plugin_init(plugin *p) {
42949         p->version     = LIGHTTPD_VERSION_ID;
42950         p->name        = buffer_init_string("access");
42951 -       
42952 +
42953         p->init        = mod_access_init;
42954         p->set_defaults = mod_access_set_defaults;
42955         p->handle_uri_clean  = mod_access_uri_handler;
42956         p->cleanup     = mod_access_free;
42957 -       
42958 +
42959         p->data        = NULL;
42960 -       
42961 +
42962         return 0;
42963  }
42964
42965 Property changes on: src/mod_access.c
42966 ___________________________________________________________________
42967 Name: svn:eol-style
42968    + native
42969
42970
42971 Property changes on: src/stream.h
42972 ___________________________________________________________________
42973 Name: svn:eol-style
42974    + native
42975
42976 Index: src/mod_accesslog.c
42977 ===================================================================
42978 --- src/mod_accesslog.c (.../tags/lighttpd-1.4.11)      (revision 1159)
42979 +++ src/mod_accesslog.c (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
42980 @@ -6,8 +6,7 @@
42981  #include <ctype.h>
42982  #include <stdlib.h>
42983  #include <string.h>
42984 -#include <fcntl.h>
42985 -#include <unistd.h>
42986 +#include <fcntl.h> /* only the defines on windows */
42987  #include <errno.h>
42988  #include <time.h>
42989  
42990 @@ -22,6 +21,7 @@
42991  #include "inet_ntop_cache.h"
42992  
42993  #include "sys-socket.h"
42994 +#include "sys-files.h"
42995  
42996  #ifdef HAVE_SYSLOG_H
42997  # include <syslog.h>
42998 @@ -29,7 +29,7 @@
42999  
43000  typedef struct {
43001         char key;
43002 -       enum { 
43003 +       enum {
43004                 FORMAT_UNSET,
43005                         FORMAT_UNSUPPORTED,
43006                         FORMAT_PERCENT,
43007 @@ -41,7 +41,7 @@
43008                         FORMAT_STATUS,
43009                         FORMAT_BYTES_OUT_NO_HEADER,
43010                         FORMAT_HEADER,
43011 -                       
43012 +
43013                         FORMAT_REMOTE_ADDR,
43014                         FORMAT_LOCAL_ADDR,
43015                         FORMAT_COOKIE,
43016 @@ -59,20 +59,20 @@
43017                         FORMAT_CONNECTION_STATUS,
43018                         FORMAT_BYTES_IN,
43019                         FORMAT_BYTES_OUT,
43020 -                       
43021 +
43022                         FORMAT_RESPONSE_HEADER
43023         } type;
43024  } format_mapping;
43025  
43026  /**
43027 - * 
43028 - * 
43029 + *
43030 + *
43031   * "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""
43032 - * 
43033 + *
43034   */
43035  
43036 -const format_mapping fmap[] = 
43037 -{ 
43038 +const format_mapping fmap[] =
43039 +{
43040         { '%', FORMAT_PERCENT },
43041         { 'h', FORMAT_REMOTE_HOST },
43042         { 'l', FORMAT_REMOTE_IDENT },
43043 @@ -82,7 +82,7 @@
43044         { 's', FORMAT_STATUS },
43045         { 'b', FORMAT_BYTES_OUT_NO_HEADER },
43046         { 'i', FORMAT_HEADER },
43047 -       
43048 +
43049         { 'a', FORMAT_REMOTE_ADDR },
43050         { 'A', FORMAT_LOCAL_ADDR },
43051         { 'B', FORMAT_BYTES_OUT_NO_HEADER },
43052 @@ -103,23 +103,23 @@
43053         { 'X', FORMAT_CONNECTION_STATUS },
43054         { 'I', FORMAT_BYTES_IN },
43055         { 'O', FORMAT_BYTES_OUT },
43056 -       
43057 +
43058         { 'o', FORMAT_RESPONSE_HEADER },
43059 -       
43060 +
43061         { '\0', FORMAT_UNSET }
43062  };
43063  
43064  
43065  typedef struct {
43066         enum { FIELD_UNSET, FIELD_STRING, FIELD_FORMAT } type;
43067 -       
43068 +
43069         buffer *string;
43070         int field;
43071  } format_field;
43072  
43073  typedef struct {
43074         format_field **ptr;
43075 -       
43076 +
43077         size_t used;
43078         size_t size;
43079  } format_fields;
43080 @@ -128,39 +128,39 @@
43081         buffer *access_logfile;
43082         buffer *format;
43083         unsigned short use_syslog;
43084 -       
43085 -       
43086 +
43087 +
43088         int    log_access_fd;
43089         time_t last_generated_accesslog_ts;
43090         time_t *last_generated_accesslog_ts_ptr;
43091 -       
43092 -       
43093 +
43094 +
43095         buffer *access_logbuffer;
43096         buffer *ts_accesslog_str;
43097 -       
43098 +
43099         format_fields *parsed_format;
43100  } plugin_config;
43101  
43102  typedef struct {
43103         PLUGIN_DATA;
43104 -       
43105 +
43106         plugin_config **config_storage;
43107 -       plugin_config conf; 
43108 +       plugin_config conf;
43109  } plugin_data;
43110  
43111  INIT_FUNC(mod_accesslog_init) {
43112         plugin_data *p;
43113 -       
43114 +
43115         p = calloc(1, sizeof(*p));
43116 -       
43117 +
43118         return p;
43119  }
43120  
43121  int accesslog_parse_format(server *srv, format_fields *fields, buffer *format) {
43122         size_t i, j, k = 0, start = 0;
43123 -       
43124 +
43125         for (i = 0; i < format->used - 1; i++) {
43126 -               
43127 +
43128                 switch(format->ptr[i]) {
43129                 case '%':
43130                         if (start != i) {
43131 @@ -173,19 +173,19 @@
43132                                         fields->size += 16;
43133                                         fields->ptr = realloc(fields->ptr, fields->size * sizeof(format_fields * ));
43134                                 }
43135 -                               
43136 +
43137                                 fields->ptr[fields->used] = malloc(sizeof(format_fields));
43138                                 fields->ptr[fields->used]->type = FIELD_STRING;
43139                                 fields->ptr[fields->used]->string = buffer_init();
43140 -                               
43141 +
43142                                 buffer_copy_string_len(fields->ptr[fields->used]->string, format->ptr + start, i - start);
43143 -                               
43144 +
43145                                 fields->used++;
43146                         }
43147 -                       
43148 -                       
43149 +
43150 +
43151                         /* we need a new field */
43152 -                       
43153 +
43154                         if (fields->size == 0) {
43155                                 fields->size = 16;
43156                                 fields->used = 0;
43157 @@ -194,43 +194,43 @@
43158                                 fields->size += 16;
43159                                 fields->ptr = realloc(fields->ptr, fields->size * sizeof(format_fields * ));
43160                         }
43161 -                       
43162 +
43163                         /* search for the terminating command */
43164                         switch (format->ptr[i+1]) {
43165                         case '>':
43166                         case '<':
43167                                 /* only for s */
43168 -                               
43169 +
43170                                 for (j = 0; fmap[j].key != '\0'; j++) {
43171                                         if (fmap[j].key != format->ptr[i+2]) continue;
43172 -                                       
43173 +
43174                                         /* found key */
43175 -                                               
43176 +
43177                                         fields->ptr[fields->used] = malloc(sizeof(format_fields));
43178                                         fields->ptr[fields->used]->type = FIELD_FORMAT;
43179                                         fields->ptr[fields->used]->field = fmap[j].type;
43180                                         fields->ptr[fields->used]->string = NULL;
43181 -                                       
43182 +
43183                                         fields->used++;
43184 -                                       
43185 +
43186                                         break;
43187                                 }
43188 -                               
43189 +
43190                                 if (fmap[j].key == '\0') {
43191                                         log_error_write(srv, __FILE__, __LINE__, "ss", "config: ", "failed");
43192                                         return -1;
43193                                 }
43194 -                               
43195 +
43196                                 start = i + 3;
43197 -                               
43198 +
43199                                 break;
43200                         case '{':
43201                                 /* go forward to } */
43202 -                               
43203 +
43204                                 for (k = i+2; k < format->used - 1; k++) {
43205                                         if (format->ptr[k] == '}') break;
43206                                 }
43207 -                               
43208 +
43209                                 if (k == format->used - 1) {
43210                                         log_error_write(srv, __FILE__, __LINE__, "ss", "config: ", "failed");
43211                                         return -1;
43212 @@ -239,62 +239,62 @@
43213                                         log_error_write(srv, __FILE__, __LINE__, "ss", "config: ", "failed");
43214                                         return -1;
43215                                 }
43216 -                               
43217 +
43218                                 for (j = 0; fmap[j].key != '\0'; j++) {
43219                                         if (fmap[j].key != format->ptr[k+1]) continue;
43220 -                                       
43221 +
43222                                         /* found key */
43223 -                                               
43224 +
43225                                         fields->ptr[fields->used] = malloc(sizeof(format_fields));
43226                                         fields->ptr[fields->used]->type = FIELD_FORMAT;
43227                                         fields->ptr[fields->used]->field = fmap[j].type;
43228                                         fields->ptr[fields->used]->string = buffer_init();
43229 -                                       
43230 +
43231                                         buffer_copy_string_len(fields->ptr[fields->used]->string, format->ptr + i + 2, k - (i + 2));
43232 -                                       
43233 +
43234                                         fields->used++;
43235 -                                       
43236 +
43237                                         break;
43238                                 }
43239 -                               
43240 +
43241                                 if (fmap[j].key == '\0') {
43242                                         log_error_write(srv, __FILE__, __LINE__, "ss", "config: ", "failed");
43243                                         return -1;
43244                                 }
43245 -                               
43246 +
43247                                 start = k + 2;
43248 -                               
43249 +
43250                                 break;
43251                         default:
43252                                 for (j = 0; fmap[j].key != '\0'; j++) {
43253                                         if (fmap[j].key != format->ptr[i+1]) continue;
43254 -                                       
43255 +
43256                                         /* found key */
43257 -                                               
43258 +
43259                                         fields->ptr[fields->used] = malloc(sizeof(format_fields));
43260                                         fields->ptr[fields->used]->type = FIELD_FORMAT;
43261                                         fields->ptr[fields->used]->field = fmap[j].type;
43262                                         fields->ptr[fields->used]->string = NULL;
43263 -                                       
43264 +
43265                                         fields->used++;
43266 -                                       
43267 +
43268                                         break;
43269                                 }
43270 -                               
43271 +
43272                                 if (fmap[j].key == '\0') {
43273                                         log_error_write(srv, __FILE__, __LINE__, "ss", "config: ", "failed");
43274                                         return -1;
43275                                 }
43276 -                               
43277 +
43278                                 start = i + 2;
43279 -                               
43280 +
43281                                 break;
43282                         }
43283 -                       
43284 +
43285                         break;
43286                 }
43287         }
43288 -       
43289 +
43290         if (start < i) {
43291                 /* copy the string */
43292                 if (fields->size == 0) {
43293 @@ -305,32 +305,32 @@
43294                         fields->size += 16;
43295                         fields->ptr = realloc(fields->ptr, fields->size * sizeof(format_fields * ));
43296                 }
43297 -               
43298 +
43299                 fields->ptr[fields->used] = malloc(sizeof(format_fields));
43300                 fields->ptr[fields->used]->type = FIELD_STRING;
43301                 fields->ptr[fields->used]->string = buffer_init();
43302 -               
43303 +
43304                 buffer_copy_string_len(fields->ptr[fields->used]->string, format->ptr + start, i - start);
43305 -               
43306 +
43307                 fields->used++;
43308         }
43309 -       
43310 +
43311         return 0;
43312  }
43313  
43314  FREE_FUNC(mod_accesslog_free) {
43315         plugin_data *p = p_d;
43316         size_t i;
43317 -       
43318 +
43319         if (!p) return HANDLER_GO_ON;
43320 -       
43321 +
43322         if (p->config_storage) {
43323 -               
43324 +
43325                 for (i = 0; i < srv->config_context->used; i++) {
43326                         plugin_config *s = p->config_storage[i];
43327  
43328                         if (!s) continue;
43329 -                       
43330 +
43331                         if (s->access_logbuffer->used) {
43332                                 if (s->use_syslog) {
43333  # ifdef HAVE_SYSLOG_H
43334 @@ -342,14 +342,14 @@
43335                                         write(s->log_access_fd, s->access_logbuffer->ptr, s->access_logbuffer->used - 1);
43336                                 }
43337                         }
43338 -                       
43339 +
43340                         if (s->log_access_fd != -1) close(s->log_access_fd);
43341 -                       
43342 +
43343                         buffer_free(s->ts_accesslog_str);
43344                         buffer_free(s->access_logbuffer);
43345                         buffer_free(s->format);
43346                         buffer_free(s->access_logfile);
43347 -                       
43348 +
43349                         if (s->parsed_format) {
43350                                 size_t j;
43351                                 for (j = 0; j < s->parsed_format->used; j++) {
43352 @@ -359,36 +359,36 @@
43353                                 free(s->parsed_format->ptr);
43354                                 free(s->parsed_format);
43355                         }
43356 -                       
43357 +
43358                         free(s);
43359                 }
43360 -       
43361 +
43362                 free(p->config_storage);
43363         }
43364 -       
43365 +
43366         free(p);
43367 -       
43368 +
43369         return HANDLER_GO_ON;
43370  }
43371  
43372  SETDEFAULTS_FUNC(log_access_open) {
43373         plugin_data *p = p_d;
43374         size_t i = 0;
43375 -       
43376 -       config_values_t cv[] = { 
43377 +
43378 +       config_values_t cv[] = {
43379                 { "accesslog.filename",             NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
43380                 { "accesslog.use-syslog",           NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },
43381                 { "accesslog.format",               NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
43382                 { NULL,                             NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
43383         };
43384 -       
43385 +
43386         if (!p) return HANDLER_ERROR;
43387 -       
43388 +
43389         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
43390 -       
43391 +
43392         for (i = 0; i < srv->config_context->used; i++) {
43393                 plugin_config *s;
43394 -               
43395 +
43396                 s = calloc(1, sizeof(plugin_config));
43397                 s->access_logfile = buffer_init();
43398                 s->format = buffer_init();
43399 @@ -397,44 +397,44 @@
43400                 s->log_access_fd = -1;
43401                 s->last_generated_accesslog_ts = 0;
43402                 s->last_generated_accesslog_ts_ptr = &(s->last_generated_accesslog_ts);
43403 -               
43404 -       
43405 +
43406 +
43407                 cv[0].destination = s->access_logfile;
43408                 cv[1].destination = &(s->use_syslog);
43409                 cv[2].destination = s->format;
43410 -       
43411 +
43412                 p->config_storage[i] = s;
43413 -               
43414 +
43415                 if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
43416                         return HANDLER_ERROR;
43417                 }
43418 -               
43419 +
43420                 if (i == 0 && buffer_is_empty(s->format)) {
43421                         /* set a default logfile string */
43422 -                       
43423 +
43424                         buffer_copy_string(s->format, "%h %V %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"");
43425                 }
43426 -               
43427 +
43428                 /* parse */
43429 -               
43430 +
43431                 if (s->format->used) {
43432                         s->parsed_format = calloc(1, sizeof(*(s->parsed_format)));
43433 -                       
43434 +
43435                         if (-1 == accesslog_parse_format(srv, s->parsed_format, s->format)) {
43436  
43437 -                               log_error_write(srv, __FILE__, __LINE__, "sb", 
43438 +                               log_error_write(srv, __FILE__, __LINE__, "sb",
43439                                                 "parsing accesslog-definition failed:", s->format);
43440  
43441                                 return HANDLER_ERROR;
43442                         }
43443  #if 0
43444 -                       /* debugging */                 
43445 +                       /* debugging */
43446                         for (j = 0; j < s->parsed_format->used; j++) {
43447                                 switch (s->parsed_format->ptr[j]->type) {
43448                                 case FIELD_FORMAT:
43449 -                                       log_error_write(srv, __FILE__, __LINE__, "ssds", 
43450 +                                       log_error_write(srv, __FILE__, __LINE__, "ssds",
43451                                                         "config:", "format", s->parsed_format->ptr[j]->field,
43452 -                                                       s->parsed_format->ptr[j]->string ? 
43453 +                                                       s->parsed_format->ptr[j]->string ?
43454                                                         s->parsed_format->ptr[j]->string->ptr : "" );
43455                                         break;
43456                                 case FIELD_STRING:
43457 @@ -446,52 +446,52 @@
43458                         }
43459  #endif
43460                 }
43461 -               
43462 +
43463                 if (s->use_syslog) {
43464                         /* ignore the next checks */
43465                         continue;
43466                 }
43467 -               
43468 +
43469                 if (buffer_is_empty(s->access_logfile)) continue;
43470 -               
43471 +
43472                 if (s->access_logfile->ptr[0] == '|') {
43473  #ifdef HAVE_FORK
43474                         /* create write pipe and spawn process */
43475 -                       
43476 +
43477                         int to_log_fds[2];
43478                         pid_t pid;
43479 -                       
43480 +
43481                         if (pipe(to_log_fds)) {
43482                                 log_error_write(srv, __FILE__, __LINE__, "ss", "pipe failed: ", strerror(errno));
43483                                 return HANDLER_ERROR;
43484                         }
43485 -                       
43486 +
43487                         /* fork, execve */
43488                         switch (pid = fork()) {
43489 -                       case 0: 
43490 +                       case 0:
43491                                 /* child */
43492 -                               
43493 +
43494                                 close(STDIN_FILENO);
43495                                 dup2(to_log_fds[0], STDIN_FILENO);
43496                                 close(to_log_fds[0]);
43497                                 /* not needed */
43498                                 close(to_log_fds[1]);
43499 -                               
43500 +
43501                                 /* we don't need the client socket */
43502                                 for (i = 3; i < 256; i++) {
43503                                         close(i);
43504                                 }
43505 -                               
43506 -                               /* exec the log-process (skip the | ) 
43507 -                                * 
43508 +
43509 +                               /* exec the log-process (skip the | )
43510 +                                *
43511                                  */
43512 -                               
43513 +
43514                                 execl("/bin/sh", "sh", "-c", s->access_logfile->ptr + 1, NULL);
43515  
43516 -                               log_error_write(srv, __FILE__, __LINE__, "sss", 
43517 -                                               "spawning log-process failed: ", strerror(errno), 
43518 +                               log_error_write(srv, __FILE__, __LINE__, "sss",
43519 +                                               "spawning log-process failed: ", strerror(errno),
43520                                                 s->access_logfile->ptr + 1);
43521 -                               
43522 +
43523                                 exit(-1);
43524                                 break;
43525                         case -1:
43526 @@ -500,27 +500,28 @@
43527                                 break;
43528                         default:
43529                                 close(to_log_fds[0]);
43530 -                               
43531 +
43532                                 s->log_access_fd = to_log_fds[1];
43533 -                               
43534 +
43535                                 break;
43536                         }
43537  #else
43538                         return -1;
43539  #endif
43540 -               } else if (-1 == (s->log_access_fd = 
43541 +               } else if (-1 == (s->log_access_fd =
43542                                   open(s->access_logfile->ptr, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
43543 -                       
43544 -                       log_error_write(srv, __FILE__, __LINE__, "ssb", 
43545 -                                       "opening access-log failed:", 
43546 +
43547 +                       log_error_write(srv, __FILE__, __LINE__, "ssb",
43548 +                                       "opening access-log failed:",
43549                                         strerror(errno), s->access_logfile);
43550 -                       
43551 +
43552                         return HANDLER_ERROR;
43553                 }
43554 +#ifndef _WIN32
43555                 fcntl(s->log_access_fd, F_SETFD, FD_CLOEXEC);
43556 -       
43557 +#endif
43558         }
43559 -       
43560 +
43561         return HANDLER_GO_ON;
43562  }
43563  
43564 @@ -529,7 +530,7 @@
43565         size_t i;
43566  
43567         if (!p->config_storage) return HANDLER_GO_ON;
43568 -               
43569 +
43570         for (i = 0; i < srv->config_context->used; i++) {
43571                 plugin_config *s = p->config_storage[i];
43572  
43573 @@ -544,90 +545,87 @@
43574                         } else if (s->log_access_fd != -1) {
43575                                 write(s->log_access_fd, s->access_logbuffer->ptr, s->access_logbuffer->used - 1);
43576                         }
43577 -                       
43578 +
43579                         buffer_reset(s->access_logbuffer);
43580                 }
43581 -               
43582 +
43583                 if (s->use_syslog == 0 &&
43584                     !buffer_is_empty(s->access_logfile) &&
43585                     s->access_logfile->ptr[0] != '|') {
43586 -                       
43587 +
43588                         close(s->log_access_fd);
43589 -                       
43590 -                       if (-1 == (s->log_access_fd = 
43591 +
43592 +                       if (-1 == (s->log_access_fd =
43593                                    open(s->access_logfile->ptr, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
43594 -                               
43595 +
43596                                 log_error_write(srv, __FILE__, __LINE__, "ss", "cycling access-log failed:", strerror(errno));
43597 -                               
43598 +
43599                                 return HANDLER_ERROR;
43600                         }
43601                 }
43602         }
43603 -       
43604 +
43605         return HANDLER_GO_ON;
43606  }
43607  
43608 -#define PATCH(x) \
43609 -       p->conf.x = s->x;
43610  static int mod_accesslog_patch_connection(server *srv, connection *con, plugin_data *p) {
43611         size_t i, j;
43612         plugin_config *s = p->config_storage[0];
43613 -       
43614 -       PATCH(access_logfile);
43615 -       PATCH(format);
43616 -       PATCH(log_access_fd);
43617 -       PATCH(last_generated_accesslog_ts_ptr);
43618 -       PATCH(access_logbuffer);
43619 -       PATCH(ts_accesslog_str);
43620 -       PATCH(parsed_format);
43621 -       PATCH(use_syslog);
43622 -       
43623 +
43624 +       PATCH_OPTION(access_logfile);
43625 +       PATCH_OPTION(format);
43626 +       PATCH_OPTION(log_access_fd);
43627 +       PATCH_OPTION(last_generated_accesslog_ts_ptr);
43628 +       PATCH_OPTION(access_logbuffer);
43629 +       PATCH_OPTION(ts_accesslog_str);
43630 +       PATCH_OPTION(parsed_format);
43631 +       PATCH_OPTION(use_syslog);
43632 +
43633         /* skip the first, the global context */
43634         for (i = 1; i < srv->config_context->used; i++) {
43635                 data_config *dc = (data_config *)srv->config_context->data[i];
43636                 s = p->config_storage[i];
43637 -               
43638 +
43639                 /* condition didn't match */
43640                 if (!config_check_cond(srv, con, dc)) continue;
43641 -               
43642 +
43643                 /* merge config */
43644                 for (j = 0; j < dc->value->used; j++) {
43645                         data_unset *du = dc->value->data[j];
43646 -                       
43647 +
43648                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("accesslog.filename"))) {
43649 -                               PATCH(access_logfile);
43650 -                               PATCH(log_access_fd);
43651 -                               PATCH(last_generated_accesslog_ts_ptr);
43652 -                               PATCH(access_logbuffer);
43653 -                               PATCH(ts_accesslog_str);
43654 +                               PATCH_OPTION(access_logfile);
43655 +                               PATCH_OPTION(log_access_fd);
43656 +                               PATCH_OPTION(last_generated_accesslog_ts_ptr);
43657 +                               PATCH_OPTION(access_logbuffer);
43658 +                               PATCH_OPTION(ts_accesslog_str);
43659                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("accesslog.format"))) {
43660 -                               PATCH(format);
43661 -                               PATCH(parsed_format);
43662 +                               PATCH_OPTION(format);
43663 +                               PATCH_OPTION(parsed_format);
43664                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("accesslog.use-syslog"))) {
43665 -                               PATCH(use_syslog);
43666 +                               PATCH_OPTION(use_syslog);
43667                         }
43668                 }
43669         }
43670 -       
43671 +
43672         return 0;
43673  }
43674 -#undef PATCH
43675  
43676  REQUESTDONE_FUNC(log_access_write) {
43677         plugin_data *p = p_d;
43678         buffer *b;
43679         size_t j;
43680 -       
43681 +
43682         int newts = 0;
43683         data_string *ds;
43684 -       
43685 +
43686         mod_accesslog_patch_connection(srv, con, p);
43687 -       
43688 +
43689         b = p->conf.access_logbuffer;
43690         if (b->used == 0) {
43691                 buffer_copy_string(b, "");
43692         }
43693 -       
43694 +
43695         for (j = 0; j < p->conf.parsed_format->used; j++) {
43696                 switch(p->conf.parsed_format->ptr[j]->type) {
43697                 case FIELD_STRING:
43698 @@ -636,14 +634,14 @@
43699                 case FIELD_FORMAT:
43700                         switch(p->conf.parsed_format->ptr[j]->field) {
43701                         case FORMAT_TIMESTAMP:
43702 -                               
43703 +
43704                                 /* cache the generated timestamp */
43705                                 if (srv->cur_ts != *(p->conf.last_generated_accesslog_ts_ptr)) {
43706                                         struct tm tm;
43707  #if defined(HAVE_STRUCT_TM_GMTOFF)
43708                                         long scd, hrs, min;
43709  #endif
43710 -               
43711 +
43712                                         buffer_prepare_copy(p->conf.ts_accesslog_str, 255);
43713  #if defined(HAVE_STRUCT_TM_GMTOFF)
43714  # ifdef HAVE_LOCALTIME_R
43715 @@ -653,17 +651,17 @@
43716                                         strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, "[%d/%b/%Y:%H:%M:%S ", localtime_r(&(srv->cur_ts)));
43717  # endif
43718                                         p->conf.ts_accesslog_str->used = strlen(p->conf.ts_accesslog_str->ptr) + 1;
43719 -                                       
43720 +
43721                                         buffer_append_string(p->conf.ts_accesslog_str, tm.tm_gmtoff >= 0 ? "+" : "-");
43722 -                                       
43723 +
43724                                         scd = abs(tm.tm_gmtoff);
43725                                         hrs = scd / 3600;
43726                                         min = (scd % 3600) / 60;
43727 -                                       
43728 +
43729                                         /* hours */
43730                                         if (hrs < 10) buffer_append_string(p->conf.ts_accesslog_str, "0");
43731                                         buffer_append_long(p->conf.ts_accesslog_str, hrs);
43732 -                                       
43733 +
43734                                         if (min < 10) buffer_append_string(p->conf.ts_accesslog_str, "0");
43735                                         buffer_append_long(p->conf.ts_accesslog_str, min);
43736                                         BUFFER_APPEND_STRING_CONST(p->conf.ts_accesslog_str, "]");
43737 @@ -676,20 +674,20 @@
43738  #endif
43739                                         p->conf.ts_accesslog_str->used = strlen(p->conf.ts_accesslog_str->ptr) + 1;
43740  #endif
43741 -                                       
43742 +
43743                                         *(p->conf.last_generated_accesslog_ts_ptr) = srv->cur_ts;
43744                                         newts = 1;
43745                                 }
43746 -                               
43747 +
43748                                 buffer_append_string_buffer(b, p->conf.ts_accesslog_str);
43749 -                               
43750 +
43751                                 break;
43752                         case FORMAT_REMOTE_HOST:
43753 -       
43754 +
43755                                 /* handle inet_ntop cache */
43756 -       
43757 +
43758                                 buffer_append_string(b, inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
43759 -                               
43760 +
43761                                 break;
43762                         case FORMAT_REMOTE_IDENT:
43763                                 /* ident */
43764 @@ -710,10 +708,10 @@
43765                         case FORMAT_STATUS:
43766                                 buffer_append_long(b, con->http_status);
43767                                 break;
43768 -       
43769 +
43770                         case FORMAT_BYTES_OUT_NO_HEADER:
43771                                 if (con->bytes_written > 0) {
43772 -                                       buffer_append_off_t(b, 
43773 +                                       buffer_append_off_t(b,
43774                                                             con->bytes_written - con->bytes_header <= 0 ? 0 : con->bytes_written - con->bytes_header);
43775                                 } else {
43776                                         BUFFER_APPEND_STRING_CONST(b, "-");
43777 @@ -772,7 +770,7 @@
43778                                 }
43779                                 break;
43780                         case FORMAT_REQUEST_PROTOCOL:
43781 -                               buffer_append_string(b, 
43782 +                               buffer_append_string(b,
43783                                                      con->request.http_version == HTTP_VERSION_1_1 ? "HTTP/1.1" : "HTTP/1.0");
43784                                 break;
43785                         case FORMAT_REQUEST_METHOD:
43786 @@ -801,7 +799,7 @@
43787                                  { 'D', FORMAT_TIME_USED_MS },
43788                                  { 'e', FORMAT_ENV },
43789                                  */
43790 -                               
43791 +
43792                                 break;
43793                         }
43794                         break;
43795 @@ -809,7 +807,7 @@
43796                         break;
43797                 }
43798         }
43799 -       
43800 +
43801         BUFFER_APPEND_STRING_CONST(b, "\n");
43802  
43803         if (p->conf.use_syslog ||  /* syslog doesn't cache */
43804 @@ -828,7 +826,7 @@
43805                 }
43806                 buffer_reset(b);
43807         }
43808 -       
43809 +
43810         return HANDLER_GO_ON;
43811  }
43812  
43813 @@ -836,15 +834,15 @@
43814  int mod_accesslog_plugin_init(plugin *p) {
43815         p->version     = LIGHTTPD_VERSION_ID;
43816         p->name        = buffer_init_string("accesslog");
43817 -       
43818 +
43819         p->init        = mod_accesslog_init;
43820         p->set_defaults= log_access_open;
43821         p->cleanup     = mod_accesslog_free;
43822 -       
43823 +
43824         p->handle_request_done  = log_access_write;
43825         p->handle_sighup        = log_access_cycle;
43826 -       
43827 +
43828         p->data        = NULL;
43829 -       
43830 +
43831         return 0;
43832  }
43833
43834 Property changes on: src/mod_accesslog.c
43835 ___________________________________________________________________
43836 Name: svn:eol-style
43837    + native
43838
43839 Index: src/fdevent_linux_sysepoll.c
43840 ===================================================================
43841 --- src/fdevent_linux_sysepoll.c        (.../tags/lighttpd-1.4.11)      (revision 1159)
43842 +++ src/fdevent_linux_sysepoll.c        (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
43843 @@ -1,6 +1,5 @@
43844  #include <sys/types.h>
43845  
43846 -#include <unistd.h>
43847  #include <stdlib.h>
43848  #include <stdio.h>
43849  #include <string.h>
43850 @@ -12,6 +11,8 @@
43851  #include "settings.h"
43852  #include "buffer.h"
43853  
43854 +#include "sys-files.h"
43855 +
43856  #ifdef USE_LINUX_EPOLL
43857  static void fdevent_linux_sysepoll_free(fdevents *ev) {
43858         close(ev->epoll_fd);
43859 @@ -20,36 +21,36 @@
43860  
43861  static int fdevent_linux_sysepoll_event_del(fdevents *ev, int fde_ndx, int fd) {
43862         struct epoll_event ep;
43863 -       
43864 +
43865         if (fde_ndx < 0) return -1;
43866 -       
43867 +
43868         memset(&ep, 0, sizeof(ep));
43869 -       
43870 +
43871         ep.data.fd = fd;
43872         ep.data.ptr = NULL;
43873 -       
43874 +
43875         if (0 != epoll_ctl(ev->epoll_fd, EPOLL_CTL_DEL, fd, &ep)) {
43876                 fprintf(stderr, "%s.%d: epoll_ctl failed: %s, dying\n", __FILE__, __LINE__, strerror(errno));
43877 -               
43878 +
43879                 SEGFAULT();
43880 -               
43881 +
43882                 return 0;
43883         }
43884 -       
43885 -       
43886 +
43887 +
43888         return -1;
43889  }
43890  
43891  static int fdevent_linux_sysepoll_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
43892         struct epoll_event ep;
43893         int add = 0;
43894 -       
43895 +
43896         if (fde_ndx == -1) add = 1;
43897 -       
43898 +
43899         memset(&ep, 0, sizeof(ep));
43900 -       
43901 +
43902         ep.events = 0;
43903 -       
43904 +
43905         if (events & FDEVENT_IN)  ep.events |= EPOLLIN;
43906         if (events & FDEVENT_OUT) ep.events |= EPOLLOUT;
43907  
43908 @@ -60,20 +61,20 @@
43909          * sent.
43910          *
43911          */
43912 -       
43913 +
43914         ep.events |= EPOLLERR | EPOLLHUP /* | EPOLLET */;
43915 -       
43916 +
43917         ep.data.ptr = NULL;
43918         ep.data.fd = fd;
43919 -       
43920 +
43921         if (0 != epoll_ctl(ev->epoll_fd, add ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, fd, &ep)) {
43922                 fprintf(stderr, "%s.%d: epoll_ctl failed: %s, dying\n", __FILE__, __LINE__, strerror(errno));
43923 -               
43924 +
43925                 SEGFAULT();
43926 -               
43927 +
43928                 return 0;
43929         }
43930 -       
43931 +
43932         return fd;
43933  }
43934  
43935 @@ -83,14 +84,14 @@
43936  
43937  static int fdevent_linux_sysepoll_event_get_revent(fdevents *ev, size_t ndx) {
43938         int events = 0, e;
43939 -       
43940 +
43941         e = ev->epoll_events[ndx].events;
43942         if (e & EPOLLIN) events |= FDEVENT_IN;
43943         if (e & EPOLLOUT) events |= FDEVENT_OUT;
43944         if (e & EPOLLERR) events |= FDEVENT_ERR;
43945         if (e & EPOLLHUP) events |= FDEVENT_HUP;
43946         if (e & EPOLLPRI) events |= FDEVENT_PRI;
43947 -       
43948 +
43949         return e;
43950  }
43951  
43952 @@ -98,17 +99,17 @@
43953  # if 0
43954         fprintf(stderr, "%s.%d: %d, %d\n", __FILE__, __LINE__, ndx, ev->epoll_events[ndx].data.fd);
43955  # endif
43956 -       
43957 +
43958         return ev->epoll_events[ndx].data.fd;
43959  }
43960  
43961  static int fdevent_linux_sysepoll_event_next_fdndx(fdevents *ev, int ndx) {
43962         size_t i;
43963 -       
43964 +
43965         UNUSED(ev);
43966  
43967         i = (ndx < 0) ? 0 : ndx + 1;
43968 -       
43969 +
43970         return i;
43971  }
43972  
43973 @@ -116,17 +117,17 @@
43974         ev->type = FDEVENT_HANDLER_LINUX_SYSEPOLL;
43975  #define SET(x) \
43976         ev->x = fdevent_linux_sysepoll_##x;
43977 -       
43978 +
43979         SET(free);
43980         SET(poll);
43981 -       
43982 +
43983         SET(event_del);
43984         SET(event_add);
43985 -       
43986 +
43987         SET(event_next_fdndx);
43988         SET(event_get_fd);
43989         SET(event_get_revent);
43990 -       
43991 +
43992         if (-1 == (ev->epoll_fd = epoll_create(ev->maxfds))) {
43993                 fprintf(stderr, "%s.%d: epoll_create failed (%s), try to set server.event-handler = \"poll\" or \"select\"\n",
43994                         __FILE__, __LINE__, strerror(errno));
43995 @@ -154,7 +155,7 @@
43996  
43997         fprintf(stderr, "%s.%d: linux-sysepoll not supported, try to set server.event-handler = \"poll\" or \"select\"\n",
43998                 __FILE__, __LINE__);
43999 -       
44000 +
44001         return -1;
44002  }
44003  #endif
44004
44005 Property changes on: src/fdevent_linux_sysepoll.c
44006 ___________________________________________________________________
44007 Name: svn:eol-style
44008    + native
44009
44010 Index: src/server.c
44011 ===================================================================
44012 --- src/server.c        (.../tags/lighttpd-1.4.11)      (revision 1159)
44013 +++ src/server.c        (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
44014 @@ -1,11 +1,9 @@
44015  #include <sys/types.h>
44016 -#include <sys/time.h>
44017  #include <sys/stat.h>
44018  
44019  #include <string.h>
44020  #include <errno.h>
44021  #include <fcntl.h>
44022 -#include <unistd.h>
44023  #include <stdlib.h>
44024  #include <time.h>
44025  #include <signal.h>
44026 @@ -29,9 +27,14 @@
44027  #include "plugin.h"
44028  #include "joblist.h"
44029  #include "network_backends.h"
44030 -
44031 +#ifdef _WIN32
44032 +/* use local getopt implementation */
44033 +# undef HAVE_GETOPT_H
44034 +#endif
44035  #ifdef HAVE_GETOPT_H
44036  #include <getopt.h>
44037 +#else
44038 +#include "getopt.h"
44039  #endif
44040  
44041  #ifdef HAVE_VALGRIND_VALGRIND_H
44042 @@ -60,8 +63,16 @@
44043  /* #define USE_ALARM */
44044  #endif
44045  
44046 +#ifdef _WIN32
44047 +#undef HAVE_SIGNAL
44048 +#endif
44049 +
44050 +#include "sys-files.h"
44051 +#include "sys-process.h"
44052 +
44053  static volatile sig_atomic_t srv_shutdown = 0;
44054  static volatile sig_atomic_t graceful_shutdown = 0;
44055 +static volatile sig_atomic_t graceful_restart = 0;
44056  static volatile sig_atomic_t handle_sig_alarm = 1;
44057  static volatile sig_atomic_t handle_sig_hup = 0;
44058  
44059 @@ -72,9 +83,9 @@
44060  
44061         switch (sig) {
44062         case SIGTERM: srv_shutdown = 1; break;
44063 -       case SIGINT: 
44064 +       case SIGINT:
44065              if (graceful_shutdown) srv_shutdown = 1;
44066 -            else graceful_shutdown = 1; 
44067 +            else graceful_shutdown = 1;
44068  
44069              break;
44070         case SIGALRM: handle_sig_alarm = 1; break;
44071 @@ -86,9 +97,9 @@
44072  static void signal_handler(int sig) {
44073         switch (sig) {
44074         case SIGTERM: srv_shutdown = 1; break;
44075 -       case SIGINT: 
44076 +       case SIGINT:
44077              if (graceful_shutdown) srv_shutdown = 1;
44078 -            else graceful_shutdown = 1; 
44079 +            else graceful_shutdown = 1;
44080  
44081              break;
44082         case SIGALRM: handle_sig_alarm = 1; break;
44083 @@ -110,25 +121,26 @@
44084         signal(SIGTSTP, SIG_IGN);
44085  #endif
44086         if (0 != fork()) exit(0);
44087 -       
44088 +
44089         if (-1 == setsid()) exit(0);
44090  
44091         signal(SIGHUP, SIG_IGN);
44092  
44093         if (0 != fork()) exit(0);
44094 -       
44095 +
44096         if (0 != chdir("/")) exit(0);
44097  }
44098  #endif
44099  
44100  static server *server_init(void) {
44101         int i;
44102 -       
44103 +
44104         server *srv = calloc(1, sizeof(*srv));
44105         assert(srv);
44106 +    srv->max_fds = 1024;
44107  #define CLEAN(x) \
44108         srv->x = buffer_init();
44109 -       
44110 +
44111         CLEAN(response_header);
44112         CLEAN(parse_full_path);
44113         CLEAN(ts_debug_str);
44114 @@ -138,7 +150,7 @@
44115         CLEAN(tmp_buf);
44116         srv->empty_string = buffer_init_string("");
44117         CLEAN(cond_check_buf);
44118 -       
44119 +
44120         CLEAN(srvconf.errorlog_file);
44121         CLEAN(srvconf.groupname);
44122         CLEAN(srvconf.username);
44123 @@ -146,58 +158,58 @@
44124         CLEAN(srvconf.bindhost);
44125         CLEAN(srvconf.event_handler);
44126         CLEAN(srvconf.pid_file);
44127 -       
44128 +
44129         CLEAN(tmp_chunk_len);
44130  #undef CLEAN
44131 -       
44132 +
44133  #define CLEAN(x) \
44134         srv->x = array_init();
44135 -       
44136 +
44137         CLEAN(config_context);
44138         CLEAN(config_touched);
44139         CLEAN(status);
44140  #undef CLEAN
44141 -       
44142 +
44143         for (i = 0; i < FILE_CACHE_MAX; i++) {
44144                 srv->mtime_cache[i].str = buffer_init();
44145         }
44146 -       
44147 +
44148         srv->cur_ts = time(NULL);
44149         srv->startup_ts = srv->cur_ts;
44150 -       
44151 +
44152         srv->conns = calloc(1, sizeof(*srv->conns));
44153         assert(srv->conns);
44154 -       
44155 +
44156         srv->joblist = calloc(1, sizeof(*srv->joblist));
44157         assert(srv->joblist);
44158 -       
44159 +
44160         srv->fdwaitqueue = calloc(1, sizeof(*srv->fdwaitqueue));
44161         assert(srv->fdwaitqueue);
44162 -       
44163 +
44164         srv->srvconf.modules = array_init();
44165         srv->srvconf.modules_dir = buffer_init_string(LIBRARY_DIR);
44166         srv->srvconf.network_backend = buffer_init();
44167         srv->srvconf.upload_tempdirs = array_init();
44168 -       
44169 +
44170         /* use syslog */
44171         srv->errorlog_fd = -1;
44172         srv->errorlog_mode = ERRORLOG_STDERR;
44173  
44174         srv->split_vals = array_init();
44175 -       
44176 +
44177         return srv;
44178  }
44179  
44180  static void server_free(server *srv) {
44181         size_t i;
44182 -       
44183 +
44184         for (i = 0; i < FILE_CACHE_MAX; i++) {
44185                 buffer_free(srv->mtime_cache[i].str);
44186         }
44187 -       
44188 +
44189  #define CLEAN(x) \
44190         buffer_free(srv->x);
44191 -       
44192 +
44193         CLEAN(response_header);
44194         CLEAN(parse_full_path);
44195         CLEAN(ts_debug_str);
44196 @@ -207,7 +219,7 @@
44197         CLEAN(tmp_buf);
44198         CLEAN(empty_string);
44199         CLEAN(cond_check_buf);
44200 -       
44201 +
44202         CLEAN(srvconf.errorlog_file);
44203         CLEAN(srvconf.groupname);
44204         CLEAN(srvconf.username);
44205 @@ -217,7 +229,7 @@
44206         CLEAN(srvconf.pid_file);
44207         CLEAN(srvconf.modules_dir);
44208         CLEAN(srvconf.network_backend);
44209 -       
44210 +
44211         CLEAN(tmp_chunk_len);
44212  #undef CLEAN
44213  
44214 @@ -225,15 +237,15 @@
44215         fdevent_unregister(srv->ev, srv->fd);
44216  #endif
44217         fdevent_free(srv->ev);
44218 -       
44219 +
44220         free(srv->conns);
44221 -       
44222 +
44223         if (srv->config_storage) {
44224                 for (i = 0; i < srv->config_context->used; i++) {
44225                         specific_config *s = srv->config_storage[i];
44226  
44227                         if (!s) continue;
44228 -                       
44229 +
44230                         buffer_free(s->document_root);
44231                         buffer_free(s->server_name);
44232                         buffer_free(s->server_tag);
44233 @@ -242,32 +254,32 @@
44234                         buffer_free(s->error_handler);
44235                         buffer_free(s->errorfile_prefix);
44236                         array_free(s->mimetypes);
44237 -                       
44238 +
44239                         free(s);
44240                 }
44241                 free(srv->config_storage);
44242                 srv->config_storage = NULL;
44243         }
44244 -       
44245 +
44246  #define CLEAN(x) \
44247         array_free(srv->x);
44248 -       
44249 +
44250         CLEAN(config_context);
44251         CLEAN(config_touched);
44252         CLEAN(status);
44253         CLEAN(srvconf.upload_tempdirs);
44254  #undef CLEAN
44255 -       
44256 +
44257         joblist_free(srv, srv->joblist);
44258         fdwaitqueue_free(srv, srv->fdwaitqueue);
44259 -       
44260 +
44261         if (srv->stat_cache) {
44262                 stat_cache_free(srv->stat_cache);
44263         }
44264  
44265         array_free(srv->srvconf.modules);
44266         array_free(srv->split_vals);
44267 -       
44268 +
44269         free(srv);
44270  }
44271  
44272 @@ -281,14 +293,12 @@
44273  " - a light and fast webserver\n" \
44274  "Build-Date: " __DATE__ " " __TIME__ "\n";
44275  ;
44276 -#undef TEXT_SSL        
44277 +#undef TEXT_SSL
44278         write(STDOUT_FILENO, b, strlen(b));
44279  }
44280  
44281  static void show_features (void) {
44282 -  show_version();
44283 -  printf("\nEvent Handlers:\n\n%s",
44284 -
44285 +  const char *s = ""
44286  #ifdef USE_SELECT
44287        "\t+ select (generic)\n"
44288  #else
44289 @@ -355,11 +365,6 @@
44290  #else
44291        "\t- crypt support\n"
44292  #endif
44293 -#ifdef USE_PAM
44294 -      "\t+ PAM support\n"
44295 -#else
44296 -      "\t- PAM support\n"
44297 -#endif
44298  #ifdef USE_OPENSSL
44299        "\t+ SSL Support\n"
44300  #else
44301 @@ -371,9 +376,9 @@
44302        "\t- PCRE support\n"
44303  #endif
44304  #ifdef HAVE_MYSQL
44305 -      "\t+ mySQL support\n"
44306 +      "\t+ MySQL support\n"
44307  #else
44308 -      "\t- mySQL support\n"
44309 +      "\t- MySQL support\n"
44310  #endif
44311  #if defined(HAVE_LDAP_H) && defined(HAVE_LBER_H) && defined(HAVE_LIBLDAP) && defined(HAVE_LIBLBER)
44312        "\t+ LDAP support\n"
44313 @@ -410,8 +415,11 @@
44314  #else
44315        "\t- GDBM support\n"
44316  #endif
44317 -      "\n"
44318 -      );
44319 +      "\n";
44320 +
44321 +  show_version();
44322 +
44323 +  printf("\nEvent Handlers:\n\n%s", s);
44324  }
44325  
44326  static void show_help (void) {
44327 @@ -433,12 +441,12 @@
44328  " -h         show this help\n" \
44329  "\n"
44330  ;
44331 -#undef TEXT_SSL        
44332 +#undef TEXT_SSL
44333  #undef TEXT_IPV6
44334         write(STDOUT_FILENO, b, strlen(b));
44335  }
44336  
44337 -int main (int argc, char **argv) {
44338 +int main (int argc, char **argv, char **envp) {
44339         server *srv = NULL;
44340         int print_config = 0;
44341         int test_config = 0;
44342 @@ -447,33 +455,37 @@
44343         int num_childs = 0;
44344         int pid_fd = -1, fd;
44345         size_t i;
44346 +#ifdef _WIN32
44347 +       char *optarg = NULL;
44348 +#endif
44349 +
44350  #ifdef HAVE_SIGACTION
44351         struct sigaction act;
44352  #endif
44353  #ifdef HAVE_GETRLIMIT
44354         struct rlimit rlim;
44355  #endif
44356 -       
44357 +
44358  #ifdef USE_ALARM
44359         struct itimerval interval;
44360 -       
44361 +
44362         interval.it_interval.tv_sec = 1;
44363         interval.it_interval.tv_usec = 0;
44364         interval.it_value.tv_sec = 1;
44365         interval.it_value.tv_usec = 0;
44366  #endif
44367 -       
44368 -       
44369 +
44370 +
44371         /* for nice %b handling in strfime() */
44372         setlocale(LC_TIME, "C");
44373 -       
44374 +
44375         if (NULL == (srv = server_init())) {
44376                 fprintf(stderr, "did this really happen?\n");
44377                 return -1;
44378         }
44379 -       
44380 +
44381         /* init structs done */
44382 -       
44383 +
44384         srv->srvconf.port = 0;
44385  #ifdef HAVE_GETUID
44386         i_am_root = (getuid() == 0);
44387 @@ -481,14 +493,19 @@
44388         i_am_root = 0;
44389  #endif
44390         srv->srvconf.dont_daemonize = 0;
44391 -       
44392 +
44393         while(-1 != (o = getopt(argc, argv, "f:m:hvVDpt"))) {
44394                 switch(o) {
44395 -               case 'f': 
44396 -                       if (config_read(srv, optarg)) { 
44397 +               case 'f':
44398 +#ifdef _WIN32
44399 +                       /* evil HACK for windows, optarg is not set */
44400 +                       optarg = argv[optind-1];
44401 +#endif
44402 +                       if (config_read(srv, optarg)) {
44403                                 server_free(srv);
44404                                 return -1;
44405                         }
44406 +
44407                         break;
44408                 case 'm':
44409                         buffer_copy_string(srv->srvconf.modules_dir, optarg);
44410 @@ -497,23 +514,23 @@
44411                 case 't': test_config = 1; break;
44412                 case 'D': srv->srvconf.dont_daemonize = 1; break;
44413                 case 'v': show_version(); return 0;
44414 -               case 'V': show_features(); return 0;          
44415 +               case 'V': show_features(); return 0;
44416                 case 'h': show_help(); return 0;
44417 -               default: 
44418 +               default:
44419                         show_help();
44420                         server_free(srv);
44421                         return -1;
44422                 }
44423         }
44424 -       
44425 +
44426         if (!srv->config_storage) {
44427                 log_error_write(srv, __FILE__, __LINE__, "s",
44428                                 "No configuration available. Try using -f option.");
44429 -               
44430 +
44431                 server_free(srv);
44432                 return -1;
44433         }
44434 -       
44435 +
44436         if (print_config) {
44437                 data_unset *dc = srv->config_context->data[0];
44438                 if (dc) {
44439 @@ -533,7 +550,7 @@
44440                 server_free(srv);
44441                 return 0;
44442         }
44443 -       
44444 +
44445         /* close stdin and stdout, as they are not needed */
44446         /* move stdin to /dev/null */
44447         if (-1 != (fd = open("/dev/null", O_RDONLY))) {
44448 @@ -541,54 +558,55 @@
44449                 dup2(fd, STDIN_FILENO);
44450                 close(fd);
44451         }
44452 -       
44453 +
44454         /* move stdout to /dev/null */
44455         if (-1 != (fd = open("/dev/null", O_WRONLY))) {
44456                 close(STDOUT_FILENO);
44457                 dup2(fd, STDOUT_FILENO);
44458                 close(fd);
44459         }
44460 -       
44461 +
44462         if (0 != config_set_defaults(srv)) {
44463 -               log_error_write(srv, __FILE__, __LINE__, "s", 
44464 +               log_error_write(srv, __FILE__, __LINE__, "s",
44465                                 "setting default values failed");
44466                 server_free(srv);
44467                 return -1;
44468         }
44469 -       
44470 +
44471         /* UID handling */
44472  #ifdef HAVE_GETUID
44473         if (!i_am_root && (geteuid() == 0 || getegid() == 0)) {
44474                 /* we are setuid-root */
44475 -               
44476 -               log_error_write(srv, __FILE__, __LINE__, "s", 
44477 +
44478 +               log_error_write(srv, __FILE__, __LINE__, "s",
44479                                 "Are you nuts ? Don't apply a SUID bit to this binary");
44480 -               
44481 +
44482                 server_free(srv);
44483                 return -1;
44484         }
44485  #endif
44486 -       
44487 +
44488         /* check document-root */
44489         if (srv->config_storage[0]->document_root->used <= 1) {
44490 -               log_error_write(srv, __FILE__, __LINE__, "s", 
44491 +               log_error_write(srv, __FILE__, __LINE__, "s",
44492                                 "document-root is not set\n");
44493 -               
44494 +
44495                 server_free(srv);
44496 -               
44497 +
44498                 return -1;
44499         }
44500 -       
44501 +
44502         if (plugins_load(srv)) {
44503                 log_error_write(srv, __FILE__, __LINE__, "s",
44504                                 "loading plugins finally failed");
44505 -               
44506 +
44507                 plugins_free(srv);
44508                 server_free(srv);
44509 -               
44510 +
44511                 return -1;
44512         }
44513 -       
44514 +
44515 +#ifndef _WIN32
44516         /* open pid file BEFORE chroot */
44517         if (srv->srvconf.pid_file->used) {
44518                 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))) {
44519 @@ -598,18 +616,18 @@
44520                                         "opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
44521                                 return -1;
44522                         }
44523 -                       
44524 +
44525                         if (0 != stat(srv->srvconf.pid_file->ptr, &st)) {
44526                                 log_error_write(srv, __FILE__, __LINE__, "sbs",
44527                                                 "stating existing pid-file failed:", srv->srvconf.pid_file, strerror(errno));
44528                         }
44529 -                       
44530 +
44531                         if (!S_ISREG(st.st_mode)) {
44532                                 log_error_write(srv, __FILE__, __LINE__, "sb",
44533                                                 "pid-file exists and isn't regular file:", srv->srvconf.pid_file);
44534                                 return -1;
44535                         }
44536 -                       
44537 +
44538                         if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
44539                                 log_error_write(srv, __FILE__, __LINE__, "sbs",
44540                                                 "opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
44541 @@ -617,13 +635,14 @@
44542                         }
44543                 }
44544         }
44545 -
44546 +#endif
44547         if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
44548                 /* select limits itself
44549                  *
44550                  * as it is a hard limit and will lead to a segfault we add some safety
44551                  * */
44552 -               srv->max_fds = FD_SETSIZE - 200;
44553 +        fprintf(stderr, "%s.%d: max parallel connections: %d\r\n", __FILE__, __LINE__, FD_SETSIZE);
44554 +               srv->max_fds = FD_SETSIZE - 4;
44555         } else {
44556                 srv->max_fds = 4096;
44557         }
44558 @@ -636,7 +655,7 @@
44559  #ifdef HAVE_VALGRIND_VALGRIND_H
44560                 if (RUNNING_ON_VALGRIND) use_rlimit = 0;
44561  #endif
44562 -               
44563 +
44564  #ifdef HAVE_GETRLIMIT
44565                 if (0 != getrlimit(RLIMIT_NOFILE, &rlim)) {
44566                         log_error_write(srv, __FILE__, __LINE__,
44567 @@ -644,13 +663,13 @@
44568                                         strerror(errno));
44569                         return -1;
44570                 }
44571 -               
44572 +
44573                 if (use_rlimit && srv->srvconf.max_fds) {
44574                         /* set rlimits */
44575 -                       
44576 +
44577                         rlim.rlim_cur = srv->srvconf.max_fds;
44578                         rlim.rlim_max = srv->srvconf.max_fds;
44579 -                       
44580 +
44581                         if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) {
44582                                 log_error_write(srv, __FILE__, __LINE__,
44583                                                 "ss", "couldn't set 'max filedescriptors'",
44584 @@ -659,7 +678,7 @@
44585                         }
44586                 }
44587  
44588 -               /* #372: solaris need some fds extra for devpoll */     
44589 +               /* #372: solaris need some fds extra for devpoll */
44590                 if (rlim.rlim_cur > 10) rlim.rlim_cur -= 10;
44591  
44592                 if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
44593 @@ -677,33 +696,33 @@
44594                 if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
44595                         /* don't raise the limit above FD_SET_SIZE */
44596                         if (srv->max_fds > FD_SETSIZE - 200) {
44597 -                               log_error_write(srv, __FILE__, __LINE__, "sd", 
44598 +                               log_error_write(srv, __FILE__, __LINE__, "sd",
44599                                                 "can't raise max filedescriptors above",  FD_SETSIZE - 200,
44600                                                 "if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds.");
44601                                 return -1;
44602                         }
44603                 }
44604  
44605 -               
44606 +
44607  #ifdef HAVE_PWD_H
44608                 /* set user and group */
44609                 if (srv->srvconf.username->used) {
44610                         if (NULL == (pwd = getpwnam(srv->srvconf.username->ptr))) {
44611 -                               log_error_write(srv, __FILE__, __LINE__, "sb", 
44612 +                               log_error_write(srv, __FILE__, __LINE__, "sb",
44613                                                 "can't find username", srv->srvconf.username);
44614                                 return -1;
44615                         }
44616 -                       
44617 +
44618                         if (pwd->pw_uid == 0) {
44619                                 log_error_write(srv, __FILE__, __LINE__, "s",
44620                                                 "I will not set uid to 0\n");
44621                                 return -1;
44622                         }
44623                 }
44624 -               
44625 +
44626                 if (srv->srvconf.groupname->used) {
44627                         if (NULL == (grp = getgrnam(srv->srvconf.groupname->ptr))) {
44628 -                               log_error_write(srv, __FILE__, __LINE__, "sb", 
44629 +                               log_error_write(srv, __FILE__, __LINE__, "sb",
44630                                         "can't find groupname", srv->srvconf.groupname);
44631                                 return -1;
44632                         }
44633 @@ -713,15 +732,15 @@
44634                                 return -1;
44635                         }
44636                 }
44637 -#endif         
44638 +#endif
44639                 /* we need root-perms for port < 1024 */
44640                 if (0 != network_init(srv)) {
44641                         plugins_free(srv);
44642                         server_free(srv);
44643 -                       
44644 +
44645                         return -1;
44646                 }
44647 -#ifdef HAVE_CHROOT     
44648 +#ifdef HAVE_CHROOT
44649                 if (srv->srvconf.changeroot->used) {
44650                         tzset();
44651  
44652 @@ -761,7 +780,7 @@
44653                 }
44654  
44655                 if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
44656 -                       srv->max_fds = rlim.rlim_cur < FD_SETSIZE - 200 ? rlim.rlim_cur : FD_SETSIZE - 200;
44657 +                       srv->max_fds = rlim.rlim_cur < FD_SETSIZE - 4 ? rlim.rlim_cur : FD_SETSIZE - 4;
44658                 } else {
44659                         srv->max_fds = rlim.rlim_cur;
44660                 }
44661 @@ -775,18 +794,18 @@
44662  #endif
44663                 if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
44664                         /* don't raise the limit above FD_SET_SIZE */
44665 -                       if (srv->max_fds > FD_SETSIZE - 200) {
44666 -                               log_error_write(srv, __FILE__, __LINE__, "sd", 
44667 -                                               "can't raise max filedescriptors above",  FD_SETSIZE - 200,
44668 +                       if (srv->max_fds > FD_SETSIZE - 4) {
44669 +                               log_error_write(srv, __FILE__, __LINE__, "sd",
44670 +                                               "can't raise max filedescriptors above",  FD_SETSIZE - 4,
44671                                                 "if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds.");
44672                                 return -1;
44673                         }
44674                 }
44675 -               
44676 +
44677                 if (0 != network_init(srv)) {
44678                         plugins_free(srv);
44679                         server_free(srv);
44680 -                       
44681 +
44682                         return -1;
44683                 }
44684         }
44685 @@ -802,25 +821,27 @@
44686                 /* or use the default */
44687                 srv->max_conns = srv->max_fds;
44688         }
44689 -       
44690 +
44691         if (HANDLER_GO_ON != plugins_call_init(srv)) {
44692                 log_error_write(srv, __FILE__, __LINE__, "s", "Initialization of plugins failed. Going down.");
44693 -               
44694 +
44695                 plugins_free(srv);
44696                 network_close(srv);
44697                 server_free(srv);
44698 -               
44699 +
44700                 return -1;
44701         }
44702  
44703 -#ifdef HAVE_FORK       
44704 +#ifdef HAVE_FORK
44705         /* network is up, let's deamonize ourself */
44706         if (srv->srvconf.dont_daemonize == 0) daemonize();
44707  #endif
44708  
44709 +#ifdef HAVE_PWD_H
44710         srv->gid = getgid();
44711         srv->uid = getuid();
44712 -       
44713 +#endif
44714 +
44715         /* write pid file */
44716         if (pid_fd != -1) {
44717                 buffer_copy_long(srv->tmp_buf, getpid());
44718 @@ -829,17 +850,17 @@
44719                 close(pid_fd);
44720                 pid_fd = -1;
44721         }
44722 -       
44723 +
44724         if (HANDLER_GO_ON != plugins_call_set_defaults(srv)) {
44725                 log_error_write(srv, __FILE__, __LINE__, "s", "Configuration of plugins failed. Going down.");
44726 -               
44727 +
44728                 plugins_free(srv);
44729                 network_close(srv);
44730                 server_free(srv);
44731 -               
44732 +
44733                 return -1;
44734         }
44735 -       
44736 +
44737         /* dump unused config-keys */
44738         for (i = 0; i < srv->config_context->used; i++) {
44739                 array *config = ((data_config *)srv->config_context->data[i])->value;
44740 @@ -847,43 +868,42 @@
44741  
44742                 for (j = 0; config && j < config->used; j++) {
44743                         data_unset *du = config->data[j];
44744 -                       
44745 +
44746                         /* all var.* is known as user defined variable */
44747                         if (strncmp(du->key->ptr, "var.", sizeof("var.") - 1) == 0) {
44748                                 continue;
44749                         }
44750  
44751                         if (NULL == array_get_element(srv->config_touched, du->key->ptr)) {
44752 -                               log_error_write(srv, __FILE__, __LINE__, "sbs", 
44753 +                               log_error_write(srv, __FILE__, __LINE__, "sbs",
44754                                                 "WARNING: unknown config-key:",
44755                                                 du->key,
44756                                                 "(ignored)");
44757                         }
44758                 }
44759         }
44760 -       
44761 +
44762         if (srv->config_deprecated) {
44763 -               log_error_write(srv, __FILE__, __LINE__, "s", 
44764 +               log_error_write(srv, __FILE__, __LINE__, "s",
44765                                 "Configuration contains deprecated keys. Going down.");
44766 -               
44767 +
44768                 plugins_free(srv);
44769                 network_close(srv);
44770                 server_free(srv);
44771 -               
44772 +
44773                 return -1;
44774         }
44775 -       
44776 +
44777         if (-1 == log_error_open(srv)) {
44778 -               log_error_write(srv, __FILE__, __LINE__, "s", 
44779 +               log_error_write(srv, __FILE__, __LINE__, "s",
44780                                 "opening errorlog failed, dying");
44781 -               
44782 +
44783                 plugins_free(srv);
44784                 network_close(srv);
44785                 server_free(srv);
44786                 return -1;
44787         }
44788 -       
44789 -       
44790 +
44791  #ifdef HAVE_SIGACTION
44792         memset(&act, 0, sizeof(act));
44793         act.sa_handler = SIG_IGN;
44794 @@ -903,7 +923,7 @@
44795         sigaction(SIGHUP,  &act, NULL);
44796         sigaction(SIGALRM, &act, NULL);
44797         sigaction(SIGCHLD, &act, NULL);
44798 -       
44799 +
44800  #elif defined(HAVE_SIGNAL)
44801         /* ignore the SIGPIPE from sendfile() */
44802         signal(SIGPIPE, SIG_IGN);
44803 @@ -914,20 +934,20 @@
44804         signal(SIGCHLD,  signal_handler);
44805         signal(SIGINT,  signal_handler);
44806  #endif
44807 -       
44808 +
44809  #ifdef USE_ALARM
44810         signal(SIGALRM, signal_handler);
44811 -       
44812 +
44813         /* setup periodic timer (1 second) */
44814         if (setitimer(ITIMER_REAL, &interval, NULL)) {
44815                 log_error_write(srv, __FILE__, __LINE__, "s", "setting timer failed");
44816                 return -1;
44817         }
44818 -       
44819 +
44820         getitimer(ITIMER_REAL, &interval);
44821  #endif
44822  
44823 -#ifdef HAVE_FORK       
44824 +#ifdef HAVE_FORK
44825         /* start watcher and workers */
44826         num_childs = srv->srvconf.max_worker;
44827         if (num_childs > 0) {
44828 @@ -957,13 +977,13 @@
44829         }
44830  #endif
44831  
44832 -       if (NULL == (srv->ev = fdevent_init(srv->max_fds + 1, srv->event_handler))) {
44833 +       if (NULL == (srv->ev = fdevent_init(/*srv->max_fds + 1*/ 4096, srv->event_handler))) {
44834                 log_error_write(srv, __FILE__, __LINE__,
44835                                 "s", "fdevent_init failed");
44836                 return -1;
44837         }
44838 -       /* 
44839 -        * kqueue() is called here, select resets its internals, 
44840 +       /*
44841 +        * kqueue() is called here, select resets its internals,
44842          * all server sockets get their handlers
44843          *
44844          * */
44845 @@ -971,7 +991,7 @@
44846                 plugins_free(srv);
44847                 network_close(srv);
44848                 server_free(srv);
44849 -               
44850 +
44851                 return -1;
44852         }
44853  
44854 @@ -986,7 +1006,7 @@
44855         /* setup FAM */
44856         if (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_FAM) {
44857                 if (0 != FAMOpen2(srv->stat_cache->fam, "lighttpd")) {
44858 -                       log_error_write(srv, __FILE__, __LINE__, "s", 
44859 +                       log_error_write(srv, __FILE__, __LINE__, "s",
44860                                          "could not open a fam connection, dieing.");
44861                         return -1;
44862                 }
44863 @@ -1018,16 +1038,40 @@
44864                 int n;
44865                 size_t ndx;
44866                 time_t min_ts;
44867 -               
44868 +
44869                 if (handle_sig_hup) {
44870                         handler_t r;
44871 -                       
44872 +
44873                         /* reset notification */
44874                         handle_sig_hup = 0;
44875 -                       
44876 -                       
44877 +
44878 +#if 0
44879 +                               pid_t pid;
44880 +
44881 +                       /* send the old process into a graceful-shutdown and start a
44882 +                        * new process right away
44883 +                        *
44884 +                        * BUGS:
44885 +                        * - if webserver is running on port < 1024 (e.g. 80, 433)
44886 +                        *   we don't have the permissions to bind to that port anymore
44887 +                        *
44888 +                        *
44889 +                        *  */
44890 +                       if (0 == (pid = fork())) {
44891 +                               execve(argv[0], argv, envp);
44892 +
44893 +                               exit(-1);
44894 +                       } else if (pid == -1) {
44895 +
44896 +                       } else {
44897 +                               /* parent */
44898 +
44899 +                               graceful_shutdown = 1; /* shutdown without killing running connections */
44900 +                               graceful_restart = 1;  /* don't delete pid file */
44901 +                       }
44902 +#else
44903                         /* cycle logfiles */
44904 -                       
44905 +
44906                         switch(r = plugins_call_handle_sighup(srv)) {
44907                         case HANDLER_GO_ON:
44908                                 break;
44909 @@ -1035,30 +1079,31 @@
44910                                 log_error_write(srv, __FILE__, __LINE__, "sd", "sighup-handler return with an error", r);
44911                                 break;
44912                         }
44913 -                       
44914 +
44915                         if (-1 == log_error_cycle(srv)) {
44916                                 log_error_write(srv, __FILE__, __LINE__, "s", "cycling errorlog failed, dying");
44917 -                               
44918 +
44919                                 return -1;
44920                         }
44921 +#endif
44922                 }
44923 -               
44924 +
44925                 if (handle_sig_alarm) {
44926                         /* a new second */
44927 -                       
44928 +
44929  #ifdef USE_ALARM
44930                         /* reset notification */
44931                         handle_sig_alarm = 0;
44932  #endif
44933 -                       
44934 +
44935                         /* get current time */
44936                         min_ts = time(NULL);
44937 -                       
44938 +
44939                         if (min_ts != srv->cur_ts) {
44940                                 int cs = 0;
44941                                 connections *conns = srv->conns;
44942                                 handler_t r;
44943 -                               
44944 +
44945                                 switch(r = plugins_call_handle_trigger(srv)) {
44946                                 case HANDLER_GO_ON:
44947                                         break;
44948 @@ -1069,21 +1114,21 @@
44949                                         log_error_write(srv, __FILE__, __LINE__, "d", r);
44950                                         break;
44951                                 }
44952 -                               
44953 +
44954                                 /* trigger waitpid */
44955                                 srv->cur_ts = min_ts;
44956 -                       
44957 -                               /* cleanup stat-cache */        
44958 +
44959 +                               /* cleanup stat-cache */
44960                                 stat_cache_trigger_cleanup(srv);
44961                                 /**
44962 -                                * check all connections for timeouts 
44963 -                                * 
44964 +                                * check all connections for timeouts
44965 +                                *
44966                                  */
44967                                 for (ndx = 0; ndx < conns->used; ndx++) {
44968                                         int changed = 0;
44969                                         connection *con;
44970                                         int t_diff;
44971 -                                       
44972 +
44973                                         con = conns->ptr[ndx];
44974  
44975                                         if (con->state == CON_STATE_READ ||
44976 @@ -1092,7 +1137,7 @@
44977                                                         if (srv->cur_ts - con->read_idle_ts > con->conf.max_read_idle) {
44978                                                                 /* time - out */
44979  #if 0
44980 -                                                               log_error_write(srv, __FILE__, __LINE__, "sd", 
44981 +                                                               log_error_write(srv, __FILE__, __LINE__, "sd",
44982                                                                                 "connection closed - read-timeout:", con->fd);
44983  #endif
44984                                                                 connection_set_state(srv, con, CON_STATE_ERROR);
44985 @@ -1102,7 +1147,7 @@
44986                                                         if (srv->cur_ts - con->read_idle_ts > con->conf.max_keep_alive_idle) {
44987                                                                 /* time - out */
44988  #if 0
44989 -                                                               log_error_write(srv, __FILE__, __LINE__, "sd", 
44990 +                                                               log_error_write(srv, __FILE__, __LINE__, "sd",
44991                                                                                 "connection closed - read-timeout:", con->fd);
44992  #endif
44993                                                                 connection_set_state(srv, con, CON_STATE_ERROR);
44994 @@ -1110,20 +1155,20 @@
44995                                                         }
44996                                                 }
44997                                         }
44998 -                                       
44999 +
45000                                         if ((con->state == CON_STATE_WRITE) &&
45001 -                                           (con->write_request_ts != 0)) { 
45002 +                                           (con->write_request_ts != 0)) {
45003  #if 0
45004                                                 if (srv->cur_ts - con->write_request_ts > 60) {
45005 -                                                       log_error_write(srv, __FILE__, __LINE__, "sdd", 
45006 +                                                       log_error_write(srv, __FILE__, __LINE__, "sdd",
45007                                                                         "connection closed - pre-write-request-timeout:", con->fd, srv->cur_ts - con->write_request_ts);
45008                                                 }
45009  #endif
45010 -                                               
45011 +
45012                                                 if (srv->cur_ts - con->write_request_ts > con->conf.max_write_idle) {
45013                                                         /* time - out */
45014  #if 1
45015 -                                                       log_error_write(srv, __FILE__, __LINE__, "sbsosds", 
45016 +                                                       log_error_write(srv, __FILE__, __LINE__, "sbsosds",
45017                                                                         "NOTE: a request for",
45018                                                                         con->request.uri,
45019                                                                         "timed out after writing",
45020 @@ -1138,35 +1183,35 @@
45021                                         }
45022                                         /* we don't like div by zero */
45023                                         if (0 == (t_diff = srv->cur_ts - con->connection_start)) t_diff = 1;
45024 -       
45025 -                                       if (con->traffic_limit_reached && 
45026 -                                           (con->conf.kbytes_per_second == 0 || 
45027 +
45028 +                                       if (con->traffic_limit_reached &&
45029 +                                           (con->conf.kbytes_per_second == 0 ||
45030                                              ((con->bytes_written / t_diff) < con->conf.kbytes_per_second * 1024))) {
45031                                                 /* enable connection again */
45032                                                 con->traffic_limit_reached = 0;
45033 -                                               
45034 +
45035                                                 changed = 1;
45036                                         }
45037 -                                       
45038 +
45039                                         if (changed) {
45040                                                 connection_state_machine(srv, con);
45041                                         }
45042                                         con->bytes_written_cur_second = 0;
45043                                         *(con->conf.global_bytes_per_second_cnt_ptr) = 0;
45044 -                                       
45045 +
45046  #if 0
45047                                         if (cs == 0) {
45048                                                 fprintf(stderr, "connection-state: ");
45049                                                 cs = 1;
45050                                         }
45051 -                                       
45052 +
45053                                         fprintf(stderr, "c[%d,%d]: %s ",
45054                                                 con->fd,
45055                                                 con->fcgi.fd,
45056                                                 connection_get_state(con->state));
45057  #endif
45058                                 }
45059 -                               
45060 +
45061                                 if (cs == 1) fprintf(stderr, "\n");
45062                         }
45063                 }
45064 @@ -1181,18 +1226,18 @@
45065                                         server_socket *srv_socket = srv->srv_sockets.ptr[i];
45066                                         fdevent_event_add(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN);
45067                                 }
45068 -                       
45069 +
45070                                 log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets enabled again");
45071 -                       
45072 +
45073                                 srv->sockets_disabled = 0;
45074                         }
45075                 } else {
45076                         if ((srv->cur_fds + srv->want_fds > srv->max_fds * 0.9) || /* out of fds */
45077                             (srv->conns->used > srv->max_conns) || /* out of connections */
45078 -                           (graceful_shutdown)) { /* graceful_shutdown */ 
45079 +                           (graceful_shutdown)) { /* graceful_shutdown */
45080  
45081                                 /* disable server-fds */
45082 -                       
45083 +
45084                                 for (i = 0; i < srv->srv_sockets.used; i++) {
45085                                         server_socket *srv_socket = srv->srv_sockets.ptr[i];
45086                                         fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);
45087 @@ -1211,7 +1256,7 @@
45088                                                 /* network_close() will cleanup after us */
45089                                         }
45090                                 }
45091 -               
45092 +
45093                                 if (graceful_shutdown) {
45094                                         log_error_write(srv, __FILE__, __LINE__, "s", "[note] graceful shutdown started");
45095                                 } else if (srv->conns->used > srv->max_conns) {
45096 @@ -1219,7 +1264,7 @@
45097                                 } else {
45098                                         log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, out-of-fds");
45099                                 }
45100 -                       
45101 +
45102                                 srv->sockets_disabled = 1;
45103                         }
45104                 }
45105 @@ -1229,16 +1274,16 @@
45106                          * we are ready to terminate without harming anyone */
45107                         srv_shutdown = 1;
45108                 }
45109 -               
45110 +
45111                 /* we still have some fds to share */
45112 -               if (srv->want_fds) { 
45113 +               if (srv->want_fds) {
45114                         /* check the fdwaitqueue for waiting fds */
45115                         int free_fds = srv->max_fds - srv->cur_fds - 16;
45116                         connection *con;
45117 -                       
45118 +
45119                         for (; free_fds > 0 && NULL != (con = fdwaitqueue_unshift(srv, srv->fdwaitqueue)); free_fds--) {
45120                                 connection_state_machine(srv, con);
45121 -                               
45122 +
45123                                 srv->want_fds--;
45124                         }
45125                 }
45126 @@ -1249,27 +1294,27 @@
45127                         int fd_ndx;
45128  #if 0
45129                         if (n > 0) {
45130 -                               log_error_write(srv, __FILE__, __LINE__, "sd", 
45131 +                               log_error_write(srv, __FILE__, __LINE__, "sd",
45132                                                 "polls:", n);
45133                         }
45134 -#endif                 
45135 +#endif
45136                         fd_ndx = -1;
45137                         do {
45138                                 fdevent_handler handler;
45139                                 void *context;
45140                                 handler_t r;
45141 -                               
45142 +
45143                                 fd_ndx  = fdevent_event_next_fdndx (srv->ev, fd_ndx);
45144                                 revents = fdevent_event_get_revent (srv->ev, fd_ndx);
45145                                 fd      = fdevent_event_get_fd     (srv->ev, fd_ndx);
45146                                 handler = fdevent_get_handler(srv->ev, fd);
45147                                 context = fdevent_get_context(srv->ev, fd);
45148 -                               
45149 +
45150                                 /* connection_handle_fdevent needs a joblist_append */
45151  #if 0
45152 -                               log_error_write(srv, __FILE__, __LINE__, "sdd", 
45153 +                               log_error_write(srv, __FILE__, __LINE__, "sdd",
45154                                                 "event for", fd, revents);
45155 -#endif                         
45156 +#endif
45157                                 switch (r = (*handler)(srv, context, revents)) {
45158                                 case HANDLER_FINISHED:
45159                                 case HANDLER_GO_ON:
45160 @@ -1286,17 +1331,17 @@
45161                                 }
45162                         } while (--n > 0);
45163                 } else if (n < 0 && errno != EINTR) {
45164 -                       log_error_write(srv, __FILE__, __LINE__, "ss", 
45165 -                                       "fdevent_poll failed:", 
45166 +                       log_error_write(srv, __FILE__, __LINE__, "ss",
45167 +                                       "fdevent_poll failed:",
45168                                         strerror(errno));
45169                 }
45170 -               
45171 +
45172                 for (ndx = 0; ndx < srv->joblist->used; ndx++) {
45173                         connection *con = srv->joblist->ptr[ndx];
45174                         handler_t r;
45175 -                       
45176 +
45177                         connection_state_machine(srv, con);
45178 -                       
45179 +
45180                         switch(r = plugins_call_handle_joblist(srv, con)) {
45181                         case HANDLER_FINISHED:
45182                         case HANDLER_GO_ON:
45183 @@ -1305,32 +1350,33 @@
45184                                 log_error_write(srv, __FILE__, __LINE__, "d", r);
45185                                 break;
45186                         }
45187 -                       
45188 +
45189                         con->in_joblist = 0;
45190                 }
45191 -               
45192 +
45193                 srv->joblist->used = 0;
45194         }
45195 -       
45196 -       if (srv->srvconf.pid_file->used &&
45197 +
45198 +       if (0 == graceful_restart &&
45199 +           srv->srvconf.pid_file->used &&
45200             srv->srvconf.changeroot->used == 0) {
45201                 if (0 != unlink(srv->srvconf.pid_file->ptr)) {
45202                         if (errno != EACCES && errno != EPERM) {
45203 -                               log_error_write(srv, __FILE__, __LINE__, "sbds", 
45204 -                                               "unlink failed for:", 
45205 +                               log_error_write(srv, __FILE__, __LINE__, "sbds",
45206 +                                               "unlink failed for:",
45207                                                 srv->srvconf.pid_file,
45208                                                 errno,
45209                                                 strerror(errno));
45210                         }
45211                 }
45212         }
45213 -       
45214 +
45215         /* clean-up */
45216         log_error_close(srv);
45217         network_close(srv);
45218         connections_free(srv);
45219         plugins_free(srv);
45220         server_free(srv);
45221 -       
45222 +
45223         return 0;
45224  }
45225
45226 Property changes on: src/server.c
45227 ___________________________________________________________________
45228 Name: svn:eol-style
45229    + native
45230
45231 Index: src/mod_dirlisting.c
45232 ===================================================================
45233 --- src/mod_dirlisting.c        (.../tags/lighttpd-1.4.11)      (revision 1159)
45234 +++ src/mod_dirlisting.c        (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
45235 @@ -1,11 +1,9 @@
45236  #include <ctype.h>
45237  #include <stdlib.h>
45238  #include <string.h>
45239 -#include <dirent.h>
45240  #include <assert.h>
45241  #include <errno.h>
45242  #include <stdio.h>
45243 -#include <unistd.h>
45244  #include <time.h>
45245  
45246  #include "base.h"
45247 @@ -31,6 +29,9 @@
45248  #include <attr/attributes.h>
45249  #endif
45250  
45251 +#include "sys-files.h"
45252 +#include "sys-strings.h"
45253 +
45254  /* plugin config for all request/connections */
45255  
45256  typedef struct {
45257 @@ -54,7 +55,7 @@
45258         unsigned short hide_readme_file;
45259         unsigned short show_header;
45260         unsigned short hide_header_file;
45261 -       
45262 +
45263         excludes_buffer *excludes;
45264  
45265         buffer *external_css;
45266 @@ -63,13 +64,13 @@
45267  
45268  typedef struct {
45269         PLUGIN_DATA;
45270 -       
45271 +
45272         buffer *tmp_buf;
45273         buffer *content_charset;
45274 -       
45275 +
45276         plugin_config **config_storage;
45277 -       
45278 -       plugin_config conf; 
45279 +
45280 +       plugin_config conf;
45281  } plugin_data;
45282  
45283  excludes_buffer *excludes_buffer_init(void) {
45284 @@ -146,44 +147,44 @@
45285  /* init the plugin data */
45286  INIT_FUNC(mod_dirlisting_init) {
45287         plugin_data *p;
45288 -       
45289 +
45290         p = calloc(1, sizeof(*p));
45291  
45292         p->tmp_buf = buffer_init();
45293         p->content_charset = buffer_init();
45294 -       
45295 +
45296         return p;
45297  }
45298  
45299  /* detroy the plugin data */
45300  FREE_FUNC(mod_dirlisting_free) {
45301         plugin_data *p = p_d;
45302 -       
45303 +
45304         UNUSED(srv);
45305  
45306         if (!p) return HANDLER_GO_ON;
45307 -       
45308 +
45309         if (p->config_storage) {
45310                 size_t i;
45311                 for (i = 0; i < srv->config_context->used; i++) {
45312                         plugin_config *s = p->config_storage[i];
45313 -                       
45314 +
45315                         if (!s) continue;
45316 -                       
45317 +
45318                         excludes_buffer_free(s->excludes);
45319                         buffer_free(s->external_css);
45320                         buffer_free(s->encoding);
45321 -                       
45322 +
45323                         free(s);
45324                 }
45325                 free(p->config_storage);
45326         }
45327 -       
45328 +
45329         buffer_free(p->tmp_buf);
45330         buffer_free(p->content_charset);
45331 -       
45332 +
45333         free(p);
45334 -       
45335 +
45336         return HANDLER_GO_ON;
45337  }
45338  
45339 @@ -215,10 +216,10 @@
45340                         if (0 != excludes_buffer_append(s->excludes,
45341                                     ((data_string *)(da->value->data[j]))->value)) {
45342  #ifdef HAVE_PCRE_H
45343 -                               log_error_write(srv, __FILE__, __LINE__, "sb", 
45344 +                               log_error_write(srv, __FILE__, __LINE__, "sb",
45345                                                 "pcre-compile failed for", ((data_string *)(da->value->data[j]))->value);
45346  #else
45347 -                               log_error_write(srv, __FILE__, __LINE__, "s", 
45348 +                               log_error_write(srv, __FILE__, __LINE__, "s",
45349                                                 "pcre support is missing, please install libpcre and the headers");
45350  #endif
45351                         }
45352 @@ -233,8 +234,8 @@
45353  SETDEFAULTS_FUNC(mod_dirlisting_set_defaults) {
45354         plugin_data *p = p_d;
45355         size_t i = 0;
45356 -       
45357 -       config_values_t cv[] = { 
45358 +
45359 +       config_values_t cv[] = {
45360                 { "dir-listing.exclude",          NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION },   /* 0 */
45361                 { "dir-listing.activate",         NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
45362                 { "dir-listing.hide-dotfiles",    NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
45363 @@ -245,18 +246,18 @@
45364                 { "dir-listing.show-header",      NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 7 */
45365                 { "dir-listing.hide-header-file", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 8 */
45366                 { "server.dir-listing",           NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 9 */
45367 -               
45368 +
45369                 { NULL,                          NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
45370         };
45371 -       
45372 +
45373         if (!p) return HANDLER_ERROR;
45374 -       
45375 +
45376         p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
45377 -       
45378 +
45379         for (i = 0; i < srv->config_context->used; i++) {
45380                 plugin_config *s;
45381                 array *ca;
45382 -               
45383 +
45384                 s = calloc(1, sizeof(plugin_config));
45385                 s->excludes = excludes_buffer_init();
45386                 s->dir_listing = 0;
45387 @@ -267,7 +268,7 @@
45388                 s->show_header = 0;
45389                 s->hide_header_file = 0;
45390                 s->encoding = buffer_init();
45391 -               
45392 +
45393                 cv[0].destination = s->excludes;
45394                 cv[1].destination = &(s->dir_listing);
45395                 cv[2].destination = &(s->hide_dot_files);
45396 @@ -292,60 +293,57 @@
45397         return HANDLER_GO_ON;
45398  }
45399  
45400 -#define PATCH(x) \
45401 -       p->conf.x = s->x;
45402  static int mod_dirlisting_patch_connection(server *srv, connection *con, plugin_data *p) {
45403         size_t i, j;
45404         plugin_config *s = p->config_storage[0];
45405  
45406 -       PATCH(dir_listing);
45407 -       PATCH(external_css);
45408 -       PATCH(hide_dot_files);
45409 -       PATCH(encoding);
45410 -       PATCH(show_readme);
45411 -       PATCH(hide_readme_file);
45412 -       PATCH(show_header);
45413 -       PATCH(hide_header_file);
45414 -       PATCH(excludes);
45415 -       
45416 +       PATCH_OPTION(dir_listing);
45417 +       PATCH_OPTION(external_css);
45418 +       PATCH_OPTION(hide_dot_files);
45419 +       PATCH_OPTION(encoding);
45420 +       PATCH_OPTION(show_readme);
45421 +       PATCH_OPTION(hide_readme_file);
45422 +       PATCH_OPTION(show_header);
45423 +       PATCH_OPTION(hide_header_file);
45424 +       PATCH_OPTION(excludes);
45425 +
45426         /* skip the first, the global context */
45427         for (i = 1; i < srv->config_context->used; i++) {
45428                 data_config *dc = (data_config *)srv->config_context->data[i];
45429                 s = p->config_storage[i];
45430 -               
45431 +
45432                 /* condition didn't match */
45433                 if (!config_check_cond(srv, con, dc)) continue;
45434 -               
45435 +
45436                 /* merge config */
45437                 for (j = 0; j < dc->value->used; j++) {
45438                         data_unset *du = dc->value->data[j];
45439 -                       
45440 +
45441                         if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.activate")) ||
45442                             buffer_is_equal_string(du->key, CONST_STR_LEN("server.dir-listing"))) {
45443 -                               PATCH(dir_listing);
45444 +                               PATCH_OPTION(dir_listing);
45445                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.hide-dotfiles"))) {
45446 -                               PATCH(hide_dot_files);
45447 +                               PATCH_OPTION(hide_dot_files);
45448                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.external-css"))) {
45449 -                               PATCH(external_css);
45450 +                               PATCH_OPTION(external_css);
45451                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.encoding"))) {
45452 -                               PATCH(encoding);
45453 +                               PATCH_OPTION(encoding);
45454                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.show-readme"))) {
45455 -                               PATCH(show_readme);
45456 +                               PATCH_OPTION(show_readme);
45457                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.hide-readme-file"))) {
45458 -                               PATCH(hide_readme_file);
45459 +                               PATCH_OPTION(hide_readme_file);
45460                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.show-header"))) {
45461 -                               PATCH(show_header);
45462 +                               PATCH_OPTION(show_header);
45463                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.hide-header-file"))) {
45464 -                               PATCH(hide_header_file);
45465 +                               PATCH_OPTION(hide_header_file);
45466                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("dir-listing.excludes"))) {
45467 -                               PATCH(excludes);
45468 +                               PATCH_OPTION(excludes);
45469                         }
45470                 }
45471         }
45472 -       
45473 +
45474         return 0;
45475  }
45476 -#undef PATCH
45477  
45478  typedef struct {
45479         size_t  namelen;
45480 @@ -432,7 +430,7 @@
45481  
45482  static void http_list_directory_header(server *srv, connection *con, plugin_data *p, buffer *out) {
45483         UNUSED(srv);
45484 -       
45485 +
45486         BUFFER_APPEND_STRING_CONST(out,
45487                 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n"
45488                 "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n"
45489 @@ -492,11 +490,11 @@
45490         if (p->conf.show_header) {
45491                 stream s;
45492                 /* if we have a HEADER file, display it in <pre class="header"></pre> */
45493 -               
45494 +
45495                 buffer_copy_string_buffer(p->tmp_buf, con->physical.path);
45496 -               BUFFER_APPEND_SLASH(p->tmp_buf);
45497 +               PATHNAME_APPEND_SLASH(p->tmp_buf);
45498                 BUFFER_APPEND_STRING_CONST(p->tmp_buf, "HEADER.txt");
45499 -               
45500 +
45501                 if (-1 != stream_open(&s, p->tmp_buf)) {
45502                         BUFFER_APPEND_STRING_CONST(out, "<pre class=\"header\">");
45503                         buffer_append_string_encoded(out, s.start, s.size, ENCODING_MINIMAL_XML);
45504 @@ -531,21 +529,21 @@
45505  
45506  static void http_list_directory_footer(server *srv, connection *con, plugin_data *p, buffer *out) {
45507         UNUSED(srv);
45508 -       
45509 +
45510         BUFFER_APPEND_STRING_CONST(out,
45511                 "</tbody>\n"
45512                 "</table>\n"
45513                 "</div>\n"
45514         );
45515 -       
45516 +
45517         if (p->conf.show_readme) {
45518                 stream s;
45519                 /* if we have a README file, display it in <pre class="readme"></pre> */
45520 -               
45521 +
45522                 buffer_copy_string_buffer(p->tmp_buf,  con->physical.path);
45523 -               BUFFER_APPEND_SLASH(p->tmp_buf);
45524 +               PATHNAME_APPEND_SLASH(p->tmp_buf);
45525                 BUFFER_APPEND_STRING_CONST(p->tmp_buf, "README.txt");
45526 -               
45527 +
45528                 if (-1 != stream_open(&s, p->tmp_buf)) {
45529                         BUFFER_APPEND_STRING_CONST(out, "<pre class=\"readme\">");
45530                         buffer_append_string_encoded(out, s.start, s.size, ENCODING_MINIMAL_XML);
45531 @@ -553,7 +551,7 @@
45532                 }
45533                 stream_close(&s);
45534         }
45535 -       
45536 +
45537         BUFFER_APPEND_STRING_CONST(out,
45538                 "<div class=\"foot\">"
45539         );
45540 @@ -595,7 +593,7 @@
45541  #endif
45542  
45543         if (dir->used == 0) return -1;
45544 -       
45545 +
45546         i = dir->used - 1;
45547  
45548  #ifdef HAVE_PATHCONF
45549 @@ -606,19 +604,24 @@
45550                 name_max = 256; /* stupid default */
45551  #endif
45552         }
45553 -#elif defined __WIN32
45554 +#elif defined _WIN32
45555         name_max = FILENAME_MAX;
45556  #else
45557         name_max = NAME_MAX;
45558  #endif
45559 -       
45560 +
45561         path = malloc(dir->used + name_max);
45562         assert(path);
45563         strcpy(path, dir->ptr);
45564 +#ifdef _WIN32
45565 +    /* append \*.* to the path and keep the \ as part of the pathname */
45566 +    strcat(path, "\\*.*");
45567 +    i++;
45568 +#endif
45569         path_file = path + i;
45570  
45571         if (NULL == (dp = opendir(path))) {
45572 -               log_error_write(srv, __FILE__, __LINE__, "sbs", 
45573 +               log_error_write(srv, __FILE__, __LINE__, "sbs",
45574                         "opendir failed:", dir, strerror(errno));
45575  
45576                 free(path);
45577 @@ -633,7 +636,7 @@
45578         assert(files.ent);
45579         files.size = DIRLIST_BLOB_SIZE;
45580         files.used = 0;
45581 -       
45582 +
45583         while ((dent = readdir(dp)) != NULL) {
45584                 unsigned short exclude_match = 0;
45585  
45586 @@ -686,15 +689,17 @@
45587  #endif
45588  
45589                 i = strlen(dent->d_name);
45590 -               
45591 +
45592                 /* NOTE: the manual says, d_name is never more than NAME_MAX
45593                  *       so this should actually not be a buffer-overflow-risk
45594                  */
45595                 if (i > (size_t)name_max) continue;
45596 -               
45597 +
45598                 memcpy(path_file, dent->d_name, i + 1);
45599 -               if (stat(path, &st) != 0)
45600 +               if (stat(path, &st) != 0) {
45601 +            fprintf(stderr, "%s.%d: %s, %s\r\n", __FILE__, __LINE__, path, strerror(errno));
45602                         continue;
45603 +        }
45604  
45605                 list = &files;
45606                 if (S_ISDIR(st.st_mode))
45607 @@ -740,7 +745,7 @@
45608  #else
45609                 strftime(datebuf, sizeof(datebuf), "%Y-%b-%d %H:%M:%S", localtime(&(tmp->mtime)));
45610  #endif
45611 -               
45612 +
45613                 BUFFER_APPEND_STRING_CONST(out, "<tr><td class=\"n\"><a href=\"");
45614                 buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_REL_URI_PART);
45615                 BUFFER_APPEND_STRING_CONST(out, "/\">");
45616 @@ -758,7 +763,7 @@
45617  
45618                 content_type = NULL;
45619  #ifdef HAVE_XATTR
45620 -               
45621 +
45622                 if (con->conf.use_xattr) {
45623                         memcpy(path_file, DIRLIST_ENT_NAME(tmp), tmp->namelen + 1);
45624                         attrlen = sizeof(attrval) - 1;
45625 @@ -768,7 +773,7 @@
45626                         }
45627                 }
45628  #endif
45629 -               
45630 +
45631                 if (content_type == NULL) {
45632                         content_type = "application/octet-stream";
45633                         for (k = 0; k < con->conf.mimetypes->used; k++) {
45634 @@ -788,7 +793,7 @@
45635                                 }
45636                         }
45637                 }
45638 -                       
45639 +
45640  #ifdef HAVE_LOCALTIME_R
45641                 localtime_r(&(tmp->mtime), &tm);
45642                 strftime(datebuf, sizeof(datebuf), "%Y-%b-%d %H:%M:%S", &tm);
45643 @@ -837,36 +842,36 @@
45644  URIHANDLER_FUNC(mod_dirlisting_subrequest) {
45645         plugin_data *p = p_d;
45646         stat_cache_entry *sce = NULL;
45647 -       
45648 +
45649         UNUSED(srv);
45650 -       
45651 +
45652         if (con->physical.path->used == 0) return HANDLER_GO_ON;
45653         if (con->uri.path->used == 0) return HANDLER_GO_ON;
45654         if (con->uri.path->ptr[con->uri.path->used - 2] != '/') return HANDLER_GO_ON;
45655 -       
45656 +
45657         mod_dirlisting_patch_connection(srv, con, p);
45658  
45659         if (!p->conf.dir_listing) return HANDLER_GO_ON;
45660 -       
45661 +
45662         if (con->conf.log_request_handling) {
45663                 log_error_write(srv, __FILE__, __LINE__,  "s",  "-- handling the request as Dir-Listing");
45664                 log_error_write(srv, __FILE__, __LINE__,  "sb", "URI          :", con->uri.path);
45665         }
45666 -       
45667 +
45668         if (HANDLER_ERROR == stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
45669                 fprintf(stderr, "%s.%d: %s\n", __FILE__, __LINE__, con->physical.path->ptr);
45670                 SEGFAULT();
45671         }
45672 -       
45673 +
45674         if (!S_ISDIR(sce->st.st_mode)) return HANDLER_GO_ON;
45675 -       
45676 +
45677         if (http_list_directory(srv, con, p, con->physical.path)) {
45678                 /* dirlisting failed */
45679                 con->http_status = 403;
45680         }
45681 -       
45682 +
45683         buffer_reset(con->physical.path);
45684 -       
45685 +
45686         /* not found */
45687         return HANDLER_FINISHED;
45688  }
45689 @@ -876,13 +881,13 @@
45690  int mod_dirlisting_plugin_init(plugin *p) {
45691         p->version     = LIGHTTPD_VERSION_ID;
45692         p->name        = buffer_init_string("dirlisting");
45693 -       
45694 +
45695         p->init        = mod_dirlisting_init;
45696         p->handle_subrequest_start  = mod_dirlisting_subrequest;
45697         p->set_defaults  = mod_dirlisting_set_defaults;
45698         p->cleanup     = mod_dirlisting_free;
45699 -       
45700 +
45701         p->data        = NULL;
45702 -       
45703 +
45704         return 0;
45705  }
45706
45707 Property changes on: src/mod_dirlisting.c
45708 ___________________________________________________________________
45709 Name: svn:eol-style
45710    + native
45711
45712 Index: src/http_chunk.c
45713 ===================================================================
45714 --- src/http_chunk.c    (.../tags/lighttpd-1.4.11)      (revision 1159)
45715 +++ src/http_chunk.c    (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
45716 @@ -1,7 +1,7 @@
45717  /**
45718   * the HTTP chunk-API
45719 - * 
45720 - * 
45721 + *
45722 + *
45723   */
45724  
45725  #include <sys/types.h>
45726 @@ -9,7 +9,6 @@
45727  
45728  #include <stdlib.h>
45729  #include <fcntl.h>
45730 -#include <unistd.h>
45731  
45732  #include <stdio.h>
45733  #include <errno.h>
45734 @@ -23,19 +22,19 @@
45735  static int http_chunk_append_len(server *srv, connection *con, size_t len) {
45736         size_t i, olen = len, j;
45737         buffer *b;
45738 -       
45739 +
45740         b = srv->tmp_chunk_len;
45741 -       
45742 +
45743         if (len == 0) {
45744                 buffer_copy_string(b, "0");
45745         } else {
45746                 for (i = 0; i < 8 && len; i++) {
45747                         len >>= 4;
45748                 }
45749 -               
45750 +
45751                 /* i is the number of hex digits we have */
45752                 buffer_prepare_copy(b, i + 1);
45753 -               
45754 +
45755                 for (j = i-1, len = olen; j+1 > 0; j--) {
45756                         b->ptr[j] = (len & 0xf) + (((len & 0xf) <= 9) ? '0' : 'a' - 10);
45757                         len >>= 4;
45758 @@ -43,61 +42,61 @@
45759                 b->used = i;
45760                 b->ptr[b->used++] = '\0';
45761         }
45762 -               
45763 +
45764         buffer_append_string(b, "\r\n");
45765         chunkqueue_append_buffer(con->write_queue, b);
45766 -       
45767 +
45768         return 0;
45769  }
45770  
45771  
45772  int http_chunk_append_file(server *srv, connection *con, buffer *fn, off_t offset, off_t len) {
45773         chunkqueue *cq;
45774 -       
45775 +
45776         if (!con) return -1;
45777 -       
45778 +
45779         cq = con->write_queue;
45780 -       
45781 +
45782         if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
45783                 http_chunk_append_len(srv, con, len);
45784         }
45785 -       
45786 +
45787         chunkqueue_append_file(cq, fn, offset, len);
45788 -       
45789 +
45790         if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED && len > 0) {
45791                 chunkqueue_append_mem(cq, "\r\n", 2 + 1);
45792         }
45793 -       
45794 +
45795         return 0;
45796  }
45797  
45798  int http_chunk_append_buffer(server *srv, connection *con, buffer *mem) {
45799         chunkqueue *cq;
45800 -       
45801 +
45802         if (!con) return -1;
45803 -       
45804 +
45805         cq = con->write_queue;
45806 -       
45807 +
45808         if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
45809                 http_chunk_append_len(srv, con, mem->used - 1);
45810         }
45811 -       
45812 +
45813         chunkqueue_append_buffer(cq, mem);
45814 -       
45815 +
45816         if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED && mem->used > 0) {
45817                 chunkqueue_append_mem(cq, "\r\n", 2 + 1);
45818         }
45819 -       
45820 +
45821         return 0;
45822  }
45823  
45824  int http_chunk_append_mem(server *srv, connection *con, const char * mem, size_t len) {
45825         chunkqueue *cq;
45826 -       
45827 +
45828         if (!con) return -1;
45829 -       
45830 +
45831         cq = con->write_queue;
45832 -       
45833 +
45834         if (len == 0) {
45835                 if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
45836                         http_chunk_append_len(srv, con, 0);
45837 @@ -107,17 +106,17 @@
45838                 }
45839                 return 0;
45840         }
45841 -       
45842 +
45843         if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
45844                 http_chunk_append_len(srv, con, len - 1);
45845         }
45846 -       
45847 +
45848         chunkqueue_append_mem(cq, mem, len);
45849 -       
45850 +
45851         if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
45852                 chunkqueue_append_mem(cq, "\r\n", 2 + 1);
45853         }
45854 -       
45855 +
45856         return 0;
45857  }
45858  
45859 @@ -125,9 +124,9 @@
45860  off_t http_chunkqueue_length(server *srv, connection *con) {
45861         if (!con) {
45862                 log_error_write(srv, __FILE__, __LINE__, "s", "connection is NULL!!");
45863 -               
45864 +
45865                 return 0;
45866         }
45867 -       
45868 +
45869         return chunkqueue_length(con->write_queue);
45870  }
45871
45872 Property changes on: src/http_chunk.c
45873 ___________________________________________________________________
45874 Name: svn:eol-style
45875    + native
45876
45877
45878 Property changes on: src/server.h
45879 ___________________________________________________________________
45880 Name: svn:eol-style
45881    + native
45882
45883
45884 Property changes on: src/http_chunk.h
45885 ___________________________________________________________________
45886 Name: svn:eol-style
45887    + native
45888
45889 Index: src/sys-files.c
45890 ===================================================================
45891 --- src/sys-files.c     (.../tags/lighttpd-1.4.11)      (revision 0)
45892 +++ src/sys-files.c     (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
45893 @@ -0,0 +1,64 @@
45894 +#include "sys-files.h"
45895 +
45896 +#ifdef _WIN32
45897 +#include "buffer.h"
45898 +DIR *opendir(const char *dn) {
45899 +    DIR *d = malloc(sizeof(*d));
45900 +
45901 +    if (INVALID_HANDLE_VALUE == (d->h = FindFirstFile(dn, &(d->finddata)))) {
45902 +        return NULL;
45903 +    }
45904 +
45905 +    return d;
45906 +}
45907 +
45908 +struct dirent *readdir(DIR *d) {
45909 +    if (!d->dent.d_name) {
45910 +        /* opendir has set a finddata already, push it out */
45911 +
45912 +        d->dent.d_name = d->finddata.cFileName;
45913 +        return &(d->dent);
45914 +    }
45915 +    if (FindNextFile(d->h, &(d->finddata))) {
45916 +        d->dent.d_name = d->finddata.cFileName;
45917 +        return &(d->dent);
45918 +    } else {
45919 +        return NULL;
45920 +    }
45921 +}
45922 +
45923 +void closedir(DIR *d) {
45924 +    FindClose(d);
45925 +
45926 +    free(d);
45927 +}
45928 +
45929 +buffer *pathname_unix2local(buffer *fn) {
45930 +    size_t i;
45931 +
45932 +    for (i = 0; i < fn->used; i++) {
45933 +        if (fn->ptr[i] == '/') {
45934 +            fn->ptr[i] = '\\';
45935 +        }
45936 +    }
45937 +
45938 +    return fn;
45939 +}
45940 +
45941 +buffer *filename_unix2local(buffer *fn) {
45942 +    size_t i;
45943 +
45944 +    for (i = 0; i < fn->used; i++) {
45945 +        if (fn->ptr[i] == '/') {
45946 +            fn->ptr[i] = '\\';
45947 +        }
45948 +    }
45949 +#if 0
45950 +    buffer_prepare_append(fn, 4);
45951 +    memmove(fn->ptr + 4, fn->ptr, fn->used);
45952 +    memcpy(fn->ptr, "\\\\?\\", 4);
45953 +    fn->used += 4;
45954 +#endif
45955 +    return fn;
45956 +}
45957 +#endif
45958 \ No newline at end of file
45959
45960 Property changes on: src/sys-files.c
45961 ___________________________________________________________________
45962 Name: svn:eol-style
45963    + native
45964
45965 Index: src/network_linux_sendfile.c
45966 ===================================================================
45967 --- src/network_linux_sendfile.c        (.../tags/lighttpd-1.4.11)      (revision 1159)
45968 +++ src/network_linux_sendfile.c        (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
45969 @@ -26,122 +26,54 @@
45970  /* on linux 2.4.29 + debian/ubuntu we have crashes if this is enabled */
45971  #undef HAVE_POSIX_FADVISE
45972  
45973 -int network_write_chunkqueue_linuxsendfile(server *srv, connection *con, int fd, chunkqueue *cq) {
45974 -       chunk *c;
45975 +NETWORK_BACKEND_WRITE(linuxsendfile) {
45976 +       chunk *c, *tc;
45977         size_t chunks_written = 0;
45978 -       
45979 +
45980         for(c = cq->first; c; c = c->next, chunks_written++) {
45981                 int chunk_finished = 0;
45982 -               
45983 +               network_status_t ret;
45984 +
45985                 switch(c->type) {
45986 -               case MEM_CHUNK: {
45987 -                       char * offset;
45988 -                       size_t toSend;
45989 -                       ssize_t r;
45990 -                       
45991 -                       size_t num_chunks, i;
45992 -                       struct iovec chunks[UIO_MAXIOV];
45993 -                       chunk *tc;
45994 -                       size_t num_bytes = 0;
45995 -                       
45996 -                       /* we can't send more then SSIZE_MAX bytes in one chunk */
45997 -                       
45998 -                       /* build writev list 
45999 -                        * 
46000 -                        * 1. limit: num_chunks < UIO_MAXIOV
46001 -                        * 2. limit: num_bytes < SSIZE_MAX
46002 -                        */
46003 -                       for (num_chunks = 0, tc = c; 
46004 -                            tc && tc->type == MEM_CHUNK && num_chunks < UIO_MAXIOV; 
46005 -                            tc = tc->next, num_chunks++);
46006 -                       
46007 -                       for (tc = c, i = 0; i < num_chunks; tc = tc->next, i++) {
46008 -                               if (tc->mem->used == 0) {
46009 -                                       chunks[i].iov_base = tc->mem->ptr;
46010 -                                       chunks[i].iov_len  = 0;
46011 -                               } else {
46012 -                                       offset = tc->mem->ptr + tc->offset;
46013 -                                       toSend = tc->mem->used - 1 - tc->offset;
46014 -                               
46015 -                                       chunks[i].iov_base = offset;
46016 -                                       
46017 -                                       /* protect the return value of writev() */
46018 -                                       if (toSend > SSIZE_MAX ||
46019 -                                           num_bytes + toSend > SSIZE_MAX) {
46020 -                                               chunks[i].iov_len = SSIZE_MAX - num_bytes;
46021 -                                               
46022 -                                               num_chunks = i + 1;
46023 -                                               break;
46024 -                                       } else {
46025 -                                               chunks[i].iov_len = toSend;
46026 -                                       }
46027 -                                
46028 -                                       num_bytes += toSend;
46029 -                               }
46030 -                       }
46031 -                       
46032 -                       if ((r = writev(fd, chunks, num_chunks)) < 0) {
46033 -                               switch (errno) {
46034 -                               case EAGAIN:
46035 -                               case EINTR:
46036 -                                       r = 0;
46037 -                                       break;
46038 -                               case EPIPE:
46039 -                               case ECONNRESET:
46040 -                                       return -2;
46041 -                               default:
46042 -                                       log_error_write(srv, __FILE__, __LINE__, "ssd", 
46043 -                                                       "writev failed:", strerror(errno), fd);
46044 -                               
46045 -                                       return -1;
46046 -                               }
46047 -                       }
46048 -                       
46049 -                       /* check which chunks have been written */
46050 -                       cq->bytes_out += r;
46051 +               case MEM_CHUNK:
46052 +                       ret = network_write_chunkqueue_writev_mem(srv, con, fd, cq, c);
46053  
46054 -                       for(i = 0, tc = c; i < num_chunks; i++, tc = tc->next) {
46055 -                               if (r >= (ssize_t)chunks[i].iov_len) {
46056 -                                       /* written */
46057 -                                       r -= chunks[i].iov_len;
46058 -                                       tc->offset += chunks[i].iov_len;
46059 -                                       
46060 +                       /* check which chunks are finished now */
46061 +                       for (tc = c; tc; tc = tc->next) {
46062 +                               /* finished the chunk */
46063 +                               if (tc->offset == tc->mem->used - 1) {
46064 +                                       /* skip the first c->next as that will be done by the c = c->next in the other for()-loop */
46065                                         if (chunk_finished) {
46066 -                                               /* skip the chunks from further touches */
46067 -                                               chunks_written++;
46068                                                 c = c->next;
46069                                         } else {
46070 -                                               /* chunks_written + c = c->next is done in the for()*/
46071 -                                               chunk_finished++;
46072 +                                               chunk_finished = 1;
46073                                         }
46074                                 } else {
46075 -                                       /* partially written */
46076 -                                       
46077 -                                       tc->offset += r;
46078 -                                       chunk_finished = 0;
46079 -                                       
46080                                         break;
46081                                 }
46082                         }
46083 -                       
46084 +
46085 +                       if (ret != NETWORK_STATUS_SUCCESS) {
46086 +                               return ret;
46087 +                       }
46088 +
46089                         break;
46090 -               }
46091                 case FILE_CHUNK: {
46092                         ssize_t r;
46093                         off_t offset;
46094                         size_t toSend;
46095                         stat_cache_entry *sce = NULL;
46096 -                       
46097 +
46098                         offset = c->file.start + c->offset;
46099                         /* limit the toSend to 2^31-1 bytes in a chunk */
46100 -                       toSend = c->file.length - c->offset > ((1 << 30) - 1) ? 
46101 +                       toSend = c->file.length - c->offset > ((1 << 30) - 1) ?
46102                                 ((1 << 30) - 1) : c->file.length - c->offset;
46103 -                               
46104 -                       /* open file if not already opened */   
46105 +
46106 +                       /* open file if not already opened */
46107                         if (-1 == c->file.fd) {
46108                                 if (-1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) {
46109                                         log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
46110 -                               
46111 +
46112                                         return -1;
46113                                 }
46114  #ifdef FD_CLOEXEC
46115 @@ -151,7 +83,7 @@
46116                                 /* tell the kernel that we want to stream the file */
46117                                 if (-1 == posix_fadvise(c->file.fd, 0, 0, POSIX_FADV_SEQUENTIAL)) {
46118                                         if (ENOSYS != errno) {
46119 -                                               log_error_write(srv, __FILE__, __LINE__, "ssd", 
46120 +                                               log_error_write(srv, __FILE__, __LINE__, "ssd",
46121                                                         "posix_fadvise failed:", strerror(errno), c->file.fd);
46122                                         }
46123                                 }
46124 @@ -168,7 +100,7 @@
46125                                 case ECONNRESET:
46126                                         return -2;
46127                                 default:
46128 -                                       log_error_write(srv, __FILE__, __LINE__, "ssd", 
46129 +                                       log_error_write(srv, __FILE__, __LINE__, "ssd",
46130                                                         "sendfile failed:", strerror(errno), fd);
46131                                         return -1;
46132                                 }
46133 @@ -179,7 +111,7 @@
46134                                  *
46135                                  * - the file shrinked -> error
46136                                  * - the remote side closed inbetween -> remote-close */
46137 -       
46138 +
46139                                 if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) {
46140                                         /* file is gone ? */
46141                                         return -1;
46142 @@ -196,22 +128,22 @@
46143  #ifdef HAVE_POSIX_FADVISE
46144  #if 0
46145  #define K * 1024
46146 -#define M * 1024 K     
46147 +#define M * 1024 K
46148  #define READ_AHEAD 4 M
46149                         /* check if we need a new chunk */
46150                         if ((c->offset & ~(READ_AHEAD - 1)) != ((c->offset + r) & ~(READ_AHEAD - 1))) {
46151                                 /* tell the kernel that we want to stream the file */
46152                                 if (-1 == posix_fadvise(c->file.fd, (c->offset + r) & ~(READ_AHEAD - 1), READ_AHEAD, POSIX_FADV_NOREUSE)) {
46153 -                                       log_error_write(srv, __FILE__, __LINE__, "ssd", 
46154 +                                       log_error_write(srv, __FILE__, __LINE__, "ssd",
46155                                                 "posix_fadvise failed:", strerror(errno), c->file.fd);
46156                                 }
46157                         }
46158  #endif
46159  #endif
46160 -                       
46161 +
46162                         c->offset += r;
46163                         cq->bytes_out += r;
46164 -                       
46165 +
46166                         if (c->offset == c->file.length) {
46167                                 chunk_finished = 1;
46168  
46169 @@ -222,19 +154,19 @@
46170                                         c->file.fd = -1;
46171                                 }
46172                         }
46173 -                       
46174 +
46175                         break;
46176                 }
46177                 default:
46178 -                       
46179 +
46180                         log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
46181 -                       
46182 +
46183                         return -1;
46184                 }
46185 -               
46186 +
46187                 if (!chunk_finished) {
46188                         /* not finished yet */
46189 -                       
46190 +
46191                         break;
46192                 }
46193         }
46194
46195 Property changes on: src/network_linux_sendfile.c
46196 ___________________________________________________________________
46197 Name: svn:eol-style
46198    + native
46199
46200 Index: src/log.c
46201 ===================================================================
46202 --- src/log.c   (.../tags/lighttpd-1.4.11)      (revision 1159)
46203 +++ src/log.c   (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
46204 @@ -5,7 +5,6 @@
46205  #include <errno.h>
46206  #include <fcntl.h>
46207  #include <time.h>
46208 -#include <unistd.h>
46209  #include <string.h>
46210  #include <stdlib.h>
46211  
46212 @@ -16,6 +15,10 @@
46213  #include "config.h"
46214  #endif
46215  
46216 +#ifdef _WIN32
46217 +#undef HAVE_SYSLOG_H
46218 +#endif
46219 +
46220  #ifdef HAVE_SYSLOG_H
46221  #include <syslog.h>
46222  #endif
46223 @@ -23,6 +26,8 @@
46224  #include "log.h"
46225  #include "array.h"
46226  
46227 +#include "sys-files.h"
46228 +
46229  #ifdef HAVE_VALGRIND_VALGRIND_H
46230  #include <valgrind/valgrind.h>
46231  #endif
46232 @@ -31,38 +36,38 @@
46233  # define O_LARGEFILE 0
46234  #endif
46235  
46236 -/** 
46237 +/**
46238   * open the errorlog
46239 - * 
46240 + *
46241   * we have 3 possibilities:
46242   * - stderr (default)
46243 - * - syslog 
46244 + * - syslog
46245   * - logfile
46246 - * 
46247 + *
46248   * if the open failed, report to the user and die
46249 - * 
46250 + *
46251   */
46252  
46253  int log_error_open(server *srv) {
46254         int fd;
46255         int close_stderr = 1;
46256 -       
46257 +
46258  #ifdef HAVE_SYSLOG_H
46259         /* perhaps someone wants to use syslog() */
46260         openlog("lighttpd", LOG_CONS | LOG_PID, LOG_DAEMON);
46261  #endif
46262         srv->errorlog_mode = ERRORLOG_STDERR;
46263 -       
46264 +
46265         if (srv->srvconf.errorlog_use_syslog) {
46266                 srv->errorlog_mode = ERRORLOG_SYSLOG;
46267         } else if (!buffer_is_empty(srv->srvconf.errorlog_file)) {
46268                 const char *logfile = srv->srvconf.errorlog_file->ptr;
46269 -               
46270 +
46271                 if (-1 == (srv->errorlog_fd = open(logfile, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
46272 -                       log_error_write(srv, __FILE__, __LINE__, "SSSS", 
46273 +                       log_error_write(srv, __FILE__, __LINE__, "SSSS",
46274                                         "opening errorlog '", logfile,
46275                                         "' failed: ", strerror(errno));
46276 -                       
46277 +
46278                         return -1;
46279                 }
46280  #ifdef FD_CLOEXEC
46281 @@ -71,15 +76,15 @@
46282  #endif
46283                 srv->errorlog_mode = ERRORLOG_FILE;
46284         }
46285 -       
46286 +
46287         log_error_write(srv, __FILE__, __LINE__, "s", "server started");
46288 -       
46289 +
46290  #ifdef HAVE_VALGRIND_VALGRIND_H
46291         /* don't close stderr for debugging purposes if run in valgrind */
46292         if (RUNNING_ON_VALGRIND) close_stderr = 0;
46293  #endif
46294         if (srv->errorlog_mode == ERRORLOG_STDERR) close_stderr = 0;
46295 -       
46296 +
46297         /* move stderr to /dev/null */
46298         if (close_stderr &&
46299             -1 != (fd = open("/dev/null", O_WRONLY))) {
46300 @@ -90,33 +95,33 @@
46301         return 0;
46302  }
46303  
46304 -/** 
46305 +/**
46306   * open the errorlog
46307 - * 
46308 + *
46309   * if the open failed, report to the user and die
46310   * if no filename is given, use syslog instead
46311 - * 
46312 + *
46313   */
46314  
46315  int log_error_cycle(server *srv) {
46316         /* only cycle if we are not in syslog-mode */
46317 -       
46318 +
46319         if (srv->errorlog_mode == ERRORLOG_FILE) {
46320                 const char *logfile = srv->srvconf.errorlog_file->ptr;
46321                 /* already check of opening time */
46322 -               
46323 +
46324                 int new_fd;
46325 -               
46326 +
46327                 if (-1 == (new_fd = open(logfile, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
46328                         /* write to old log */
46329 -                       log_error_write(srv, __FILE__, __LINE__, "SSSSS", 
46330 +                       log_error_write(srv, __FILE__, __LINE__, "SSSSS",
46331                                         "cycling errorlog '", logfile,
46332                                         "' failed: ", strerror(errno),
46333                                         ", falling back to syslog()");
46334 -                       
46335 +
46336                         close(srv->errorlog_fd);
46337                         srv->errorlog_fd = -1;
46338 -#ifdef HAVE_SYSLOG_H   
46339 +#ifdef HAVE_SYSLOG_H
46340                         srv->errorlog_mode = ERRORLOG_SYSLOG;
46341  #endif
46342                 } else {
46343 @@ -125,15 +130,15 @@
46344                         srv->errorlog_fd = new_fd;
46345                 }
46346         }
46347 -       
46348 +
46349         log_error_write(srv, __FILE__, __LINE__, "s", "logfiles cycled");
46350 -       
46351 +
46352         return 0;
46353  }
46354  
46355  int log_error_close(server *srv) {
46356         log_error_write(srv, __FILE__, __LINE__, "s", "server stopped");
46357 -       
46358 +
46359         switch(srv->errorlog_mode) {
46360         case ERRORLOG_FILE:
46361                 close(srv->errorlog_fd);
46362 @@ -146,13 +151,13 @@
46363         case ERRORLOG_STDERR:
46364                 break;
46365         }
46366 -       
46367 +
46368         return 0;
46369  }
46370  
46371  int log_error_write(server *srv, const char *filename, unsigned int line, const char *fmt, ...) {
46372         va_list ap;
46373 -       
46374 +
46375         switch(srv->errorlog_mode) {
46376         case ERRORLOG_FILE:
46377         case ERRORLOG_STDERR:
46378 @@ -161,7 +166,7 @@
46379                         buffer_prepare_copy(srv->ts_debug_str, 255);
46380                         strftime(srv->ts_debug_str->ptr, srv->ts_debug_str->size - 1, "%Y-%m-%d %H:%M:%S", localtime(&(srv->cur_ts)));
46381                         srv->ts_debug_str->used = strlen(srv->ts_debug_str->ptr) + 1;
46382 -                       
46383 +
46384                         srv->last_generated_debug_ts = srv->cur_ts;
46385                 }
46386  
46387 @@ -173,19 +178,19 @@
46388                 BUFFER_COPY_STRING_CONST(srv->errorlog_buf, "(");
46389                 break;
46390         }
46391 -       
46392 +
46393         buffer_append_string(srv->errorlog_buf, filename);
46394         BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, ".");
46395         buffer_append_long(srv->errorlog_buf, line);
46396         BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, ") ");
46397 -       
46398 -       
46399 +
46400 +
46401         for(va_start(ap, fmt); *fmt; fmt++) {
46402                 int d;
46403                 char *s;
46404                 buffer *b;
46405                 off_t o;
46406 -               
46407 +
46408                 switch(*fmt) {
46409                 case 's':           /* string */
46410                         s = va_arg(ap, char *);
46411 @@ -227,7 +232,7 @@
46412                         break;
46413                 case '(':
46414                 case ')':
46415 -               case '<':       
46416 +               case '<':
46417                 case '>':
46418                 case ',':
46419                 case ' ':
46420 @@ -236,7 +241,7 @@
46421                 }
46422         }
46423         va_end(ap);
46424 -       
46425 +
46426         switch(srv->errorlog_mode) {
46427         case ERRORLOG_FILE:
46428                 BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "\n");
46429 @@ -246,11 +251,13 @@
46430                 BUFFER_APPEND_STRING_CONST(srv->errorlog_buf, "\n");
46431                 write(STDERR_FILENO, srv->errorlog_buf->ptr, srv->errorlog_buf->used - 1);
46432                 break;
46433 +#ifdef HAVE_SYSLOG_H
46434         case ERRORLOG_SYSLOG:
46435                 syslog(LOG_ERR, "%s", srv->errorlog_buf->ptr);
46436                 break;
46437 +#endif
46438         }
46439 -       
46440 +
46441         return 0;
46442  }
46443  
46444
46445 Property changes on: src/log.c
46446 ___________________________________________________________________
46447 Name: svn:eol-style
46448    + native
46449
46450 Index: src/sys-files.h
46451 ===================================================================
46452 --- src/sys-files.h     (.../tags/lighttpd-1.4.11)      (revision 0)
46453 +++ src/sys-files.h     (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
46454 @@ -0,0 +1,67 @@
46455 +#ifndef _SYS_FILES_H_
46456 +#define _SYS_FILES_H_
46457 +
46458 +#define DIR_SEPERATOR_UNIX '/'
46459 +#define DIR_SEPERATOR_WIN '\\'
46460 +
46461 +#ifdef _WIN32
46462 +#include <windows.h>
46463 +#include <io.h>     /* open */
46464 +#include <direct.h> /* chdir */
46465 +
46466 +#include "buffer.h"
46467 +
46468 +#define DIR_SEPERATOR DIR_SEPERATOR_WIN
46469 +
46470 +#define __S_ISTYPE(mode, mask)  (((mode) & _S_IFMT) == (mask))
46471 +
46472 +#define S_ISDIR(mode)    __S_ISTYPE((mode), _S_IFDIR)
46473 +#define S_ISCHR(mode)    __S_ISTYPE((mode), _S_IFCHR)
46474 +#define S_ISBLK(mode)    __S_ISTYPE((mode), _S_IFBLK)
46475 +#define S_ISREG(mode)    __S_ISTYPE((mode), _S_IFREG)
46476 +/* we don't support symlinks */
46477 +#define S_ISLNK(mode)    0
46478 +
46479 +#define lstat stat
46480 +#define mkstemp mktemp
46481 +#define mkdir(x, y) mkdir(x)
46482 +
46483 +struct dirent {
46484 +    const char *d_name;
46485 +};
46486 +
46487 +typedef struct {
46488 +    HANDLE h;
46489 +    WIN32_FIND_DATA finddata;
46490 +    struct dirent dent;
46491 +} DIR;
46492 +
46493 +DIR *opendir(const char *dn);
46494 +struct dirent *readdir(DIR *d);
46495 +void closedir(DIR *d);
46496 +
46497 +buffer *filename_unix2local(buffer *b);
46498 +buffer *pathname_unix2local(buffer *b);
46499 +
46500 +#else
46501 +#include <unistd.h>
46502 +#include <dirent.h>
46503 +
46504 +#define DIR_SEPERATOR DIR_SEPERATOR_UNIX
46505 +
46506 +#define filename_unix2local(x) (x)
46507 +#define pathname_unix2local(x) (x)
46508 +#endif
46509 +
46510 +#define PATHNAME_APPEND_SLASH(x) \
46511 +       if (x->used > 1 && x->ptr[x->used - 2] != DIR_SEPERATOR) { \
46512 +        char sl[2] = { DIR_SEPERATOR, 0 }; \
46513 +        BUFFER_APPEND_STRING_CONST(x, sl); \
46514 +    }
46515 +
46516 +#ifndef O_LARGEFILE
46517 +# define O_LARGEFILE 0
46518 +#endif
46519 +
46520 +#endif
46521 +
46522
46523 Property changes on: src/sys-files.h
46524 ___________________________________________________________________
46525 Name: svn:eol-style
46526    + native
46527
46528 Index: src/proc_open.c
46529 ===================================================================
46530 --- src/proc_open.c     (.../tags/lighttpd-1.4.11)      (revision 1159)
46531 +++ src/proc_open.c     (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
46532 @@ -13,13 +13,13 @@
46533  #endif
46534  
46535  
46536 -#ifdef WIN32
46537 +#ifdef _WIN32
46538  /* {{{ win32 stuff */
46539  # define SHELLENV "ComSpec"
46540  # define SECURITY_DC , SECURITY_ATTRIBUTES *security
46541  # define SECURITY_CC , security
46542  # define pipe(pair) (CreatePipe(&pair[0], &pair[1], security, 2048L) ? 0 : -1)
46543 -static inline HANDLE dup_handle(HANDLE src, BOOL inherit, BOOL closeorig)
46544 +static HANDLE dup_handle(HANDLE src, BOOL inherit, BOOL closeorig)
46545  {
46546         HANDLE copy, self = GetCurrentProcess();
46547  
46548 @@ -148,11 +148,14 @@
46549         STARTUPINFO si;
46550         BOOL procok;
46551         SECURITY_ATTRIBUTES security;
46552 -       const char *shell;
46553 +       const char *shell = NULL;
46554 +       const char *windir = NULL;
46555         buffer *cmdline;
46556  
46557 -       if (NULL == (shell = getenv(SHELLENV))) {
46558 -               fprintf(stderr, "env %s is required", SHELLENV);
46559 +       if (NULL == (shell = getenv(SHELLENV)) &&
46560 +                       NULL == (windir = getenv("SystemRoot")) &&
46561 +                       NULL == (windir = getenv("windir"))) {
46562 +               fprintf(stderr, "One of %s,%%SystemRoot,%%windir is required", SHELLENV);
46563                 return -1;
46564         }
46565  
46566 @@ -177,17 +180,23 @@
46567         memset(&pi, 0, sizeof(pi));
46568  
46569         cmdline = buffer_init();
46570 -       buffer_append_string(cmdline, shell);
46571 +       if (shell) {
46572 +               buffer_append_string(cmdline, shell);
46573 +       } else {
46574 +               buffer_append_string(cmdline, windir);
46575 +               buffer_append_string(cmdline, "\\system32\\cmd.exe");
46576 +       }
46577         buffer_append_string_len(cmdline, CONST_STR_LEN(" /c "));
46578         buffer_append_string(cmdline, command);
46579         procok = CreateProcess(NULL, cmdline->ptr, &security, &security, TRUE,
46580                         NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
46581 -       buffer_free(cmdline);
46582  
46583         if (FALSE == procok) {
46584 -               fprintf(stderr, "failed to CreateProcess");
46585 +               fprintf(stderr, "failed to CreateProcess: %s", cmdline->ptr);
46586 +               buffer_free(cmdline);
46587                 return -1;
46588         }
46589 +       buffer_free(cmdline);
46590  
46591         proc->child = pi.hProcess;
46592         CloseHandle(pi.hThread);
46593 @@ -226,8 +235,7 @@
46594         const char *shell;
46595  
46596         if (NULL == (shell = getenv(SHELLENV))) {
46597 -               fprintf(stderr, "env %s is required", SHELLENV);
46598 -               return -1;
46599 +               shell = "/bin/sh";
46600         }
46601  
46602         if (proc_open_pipes(proc) != 0) {
46603 @@ -262,11 +270,11 @@
46604         }
46605  }
46606  /* }}} */
46607 -#endif /* WIN32 */
46608 +#endif /* _WIN32 */
46609  
46610  /* {{{ proc_read_fd_to_buffer */
46611  static void proc_read_fd_to_buffer(int fd, buffer *b) {
46612 -       ssize_t s;
46613 +       int s; /* win32 has not ssize_t */
46614  
46615         for (;;) {
46616                 buffer_prepare_append(b, 512);
46617
46618 Property changes on: src/proc_open.c
46619 ___________________________________________________________________
46620 Name: svn:eol-style
46621    + native
46622
46623 Index: src/log.h
46624 ===================================================================
46625 --- src/log.h   (.../tags/lighttpd-1.4.11)      (revision 1159)
46626 +++ src/log.h   (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
46627 @@ -9,5 +9,5 @@
46628  int log_error_close(server *srv);
46629  int log_error_write(server *srv, const char *filename, unsigned int line, const char *fmt, ...);
46630  int log_error_cycle(server *srv);
46631 -       
46632 +
46633  #endif
46634
46635 Property changes on: src/log.h
46636 ___________________________________________________________________
46637 Name: svn:eol-style
46638    + native
46639
46640 Index: src/proc_open.h
46641 ===================================================================
46642 --- src/proc_open.h     (.../tags/lighttpd-1.4.11)      (revision 1159)
46643 +++ src/proc_open.h     (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
46644 @@ -1,7 +1,7 @@
46645  
46646  #include "buffer.h"
46647  
46648 -#ifdef WIN32
46649 +#ifdef _WIN32
46650  #include <windows.h>
46651  typedef HANDLE descriptor_t;
46652  typedef HANDLE proc_pid_t;
46653
46654 Property changes on: src/proc_open.h
46655 ___________________________________________________________________
46656 Name: svn:eol-style
46657    + native
46658
46659 Index: src/fdevent.c
46660 ===================================================================
46661 --- src/fdevent.c       (.../tags/lighttpd-1.4.11)      (revision 1159)
46662 +++ src/fdevent.c       (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
46663 @@ -2,7 +2,6 @@
46664  
46665  #include "settings.h"
46666  
46667 -#include <unistd.h>
46668  #include <stdlib.h>
46669  #include <string.h>
46670  #include <errno.h>
46671 @@ -12,59 +11,61 @@
46672  #include "fdevent.h"
46673  #include "buffer.h"
46674  
46675 +#include "sys-socket.h"
46676 +
46677  fdevents *fdevent_init(size_t maxfds, fdevent_handler_t type) {
46678         fdevents *ev;
46679 -       
46680 +
46681         ev = calloc(1, sizeof(*ev));
46682         ev->fdarray = calloc(maxfds, sizeof(*ev->fdarray));
46683         ev->maxfds = maxfds;
46684 -       
46685 +
46686         switch(type) {
46687         case FDEVENT_HANDLER_POLL:
46688                 if (0 != fdevent_poll_init(ev)) {
46689 -                       fprintf(stderr, "%s.%d: event-handler poll failed\n", 
46690 +                       fprintf(stderr, "%s.%d: event-handler poll failed\n",
46691                                 __FILE__, __LINE__);
46692 -                       
46693 +
46694                         return NULL;
46695                 }
46696                 break;
46697         case FDEVENT_HANDLER_SELECT:
46698                 if (0 != fdevent_select_init(ev)) {
46699 -                       fprintf(stderr, "%s.%d: event-handler select failed\n", 
46700 +                       fprintf(stderr, "%s.%d: event-handler select failed\n",
46701                                 __FILE__, __LINE__);
46702                         return NULL;
46703                 }
46704                 break;
46705         case FDEVENT_HANDLER_LINUX_RTSIG:
46706                 if (0 != fdevent_linux_rtsig_init(ev)) {
46707 -                       fprintf(stderr, "%s.%d: event-handler linux-rtsig failed, try to set server.event-handler = \"poll\" or \"select\"\n", 
46708 +                       fprintf(stderr, "%s.%d: event-handler linux-rtsig failed, try to set server.event-handler = \"poll\" or \"select\"\n",
46709                                 __FILE__, __LINE__);
46710                         return NULL;
46711                 }
46712                 break;
46713         case FDEVENT_HANDLER_LINUX_SYSEPOLL:
46714                 if (0 != fdevent_linux_sysepoll_init(ev)) {
46715 -                       fprintf(stderr, "%s.%d: event-handler linux-sysepoll failed, try to set server.event-handler = \"poll\" or \"select\"\n", 
46716 +                       fprintf(stderr, "%s.%d: event-handler linux-sysepoll failed, try to set server.event-handler = \"poll\" or \"select\"\n",
46717                                 __FILE__, __LINE__);
46718                         return NULL;
46719                 }
46720                 break;
46721         case FDEVENT_HANDLER_SOLARIS_DEVPOLL:
46722                 if (0 != fdevent_solaris_devpoll_init(ev)) {
46723 -                       fprintf(stderr, "%s.%d: event-handler solaris-devpoll failed, try to set server.event-handler = \"poll\" or \"select\"\n", 
46724 +                       fprintf(stderr, "%s.%d: event-handler solaris-devpoll failed, try to set server.event-handler = \"poll\" or \"select\"\n",
46725                                 __FILE__, __LINE__);
46726                         return NULL;
46727                 }
46728                 break;
46729         case FDEVENT_HANDLER_FREEBSD_KQUEUE:
46730                 if (0 != fdevent_freebsd_kqueue_init(ev)) {
46731 -                       fprintf(stderr, "%s.%d: event-handler freebsd-kqueue failed, try to set server.event-handler = \"poll\" or \"select\"\n", 
46732 +                       fprintf(stderr, "%s.%d: event-handler freebsd-kqueue failed, try to set server.event-handler = \"poll\" or \"select\"\n",
46733                                 __FILE__, __LINE__);
46734                         return NULL;
46735                 }
46736                 break;
46737         default:
46738 -               fprintf(stderr, "%s.%d: event-handler is unknown, try to set server.event-handler = \"poll\" or \"select\"\n", 
46739 +               fprintf(stderr, "%s.%d: event-handler is unknown, try to set server.event-handler = \"poll\" or \"select\"\n",
46740                         __FILE__, __LINE__);
46741                 return NULL;
46742         }
46743 @@ -75,26 +76,26 @@
46744  void fdevent_free(fdevents *ev) {
46745         size_t i;
46746         if (!ev) return;
46747 -       
46748 +
46749         if (ev->free) ev->free(ev);
46750 -       
46751 +
46752         for (i = 0; i < ev->maxfds; i++) {
46753                 if (ev->fdarray[i]) free(ev->fdarray[i]);
46754         }
46755 -       
46756 +
46757         free(ev->fdarray);
46758         free(ev);
46759  }
46760  
46761  int fdevent_reset(fdevents *ev) {
46762         if (ev->reset) return ev->reset(ev);
46763 -       
46764 +
46765         return 0;
46766  }
46767  
46768  fdnode *fdnode_init() {
46769         fdnode *fdn;
46770 -       
46771 +
46772         fdn = calloc(1, sizeof(*fdn));
46773         fdn->fd = -1;
46774         return fdn;
46775 @@ -106,12 +107,12 @@
46776  
46777  int fdevent_register(fdevents *ev, int fd, fdevent_handler handler, void *ctx) {
46778         fdnode *fdn;
46779 -       
46780 +
46781         fdn = fdnode_init();
46782         fdn->handler = handler;
46783         fdn->fd      = fd;
46784         fdn->ctx     = ctx;
46785 -       
46786 +
46787         ev->fdarray[fd] = fdn;
46788  
46789         return 0;
46790 @@ -121,31 +122,31 @@
46791         fdnode *fdn;
46792          if (!ev) return 0;
46793         fdn = ev->fdarray[fd];
46794 -       
46795 +
46796         fdnode_free(fdn);
46797 -       
46798 +
46799         ev->fdarray[fd] = NULL;
46800 -       
46801 +
46802         return 0;
46803  }
46804  
46805  int fdevent_event_del(fdevents *ev, int *fde_ndx, int fd) {
46806         int fde = fde_ndx ? *fde_ndx : -1;
46807 -       
46808 +
46809         if (ev->event_del) fde = ev->event_del(ev, fde, fd);
46810 -       
46811 +
46812         if (fde_ndx) *fde_ndx = fde;
46813 -       
46814 +
46815         return 0;
46816  }
46817  
46818  int fdevent_event_add(fdevents *ev, int *fde_ndx, int fd, int events) {
46819         int fde = fde_ndx ? *fde_ndx : -1;
46820 -       
46821 +
46822         if (ev->event_add) fde = ev->event_add(ev, fde, fd, events);
46823 -       
46824 +
46825         if (fde_ndx) *fde_ndx = fde;
46826 -       
46827 +
46828         return 0;
46829  }
46830  
46831 @@ -156,38 +157,43 @@
46832  
46833  int fdevent_event_get_revent(fdevents *ev, size_t ndx) {
46834         if (ev->event_get_revent == NULL) SEGFAULT();
46835 -       
46836 +
46837         return ev->event_get_revent(ev, ndx);
46838  }
46839  
46840  int fdevent_event_get_fd(fdevents *ev, size_t ndx) {
46841         if (ev->event_get_fd == NULL) SEGFAULT();
46842 -       
46843 +
46844         return ev->event_get_fd(ev, ndx);
46845  }
46846  
46847  fdevent_handler fdevent_get_handler(fdevents *ev, int fd) {
46848         if (ev->fdarray[fd] == NULL) SEGFAULT();
46849         if (ev->fdarray[fd]->fd != fd) SEGFAULT();
46850 -       
46851 +
46852         return ev->fdarray[fd]->handler;
46853  }
46854  
46855  void * fdevent_get_context(fdevents *ev, int fd) {
46856         if (ev->fdarray[fd] == NULL) SEGFAULT();
46857         if (ev->fdarray[fd]->fd != fd) SEGFAULT();
46858 -       
46859 +
46860         return ev->fdarray[fd]->ctx;
46861  }
46862  
46863  int fdevent_fcntl_set(fdevents *ev, int fd) {
46864 +#ifdef _WIN32
46865 +    int i = 1;
46866 +#endif
46867  #ifdef FD_CLOEXEC
46868         /* close fd on exec (cgi) */
46869         fcntl(fd, F_SETFD, FD_CLOEXEC);
46870  #endif
46871         if ((ev) && (ev->fcntl_set)) return ev->fcntl_set(ev, fd);
46872 -#ifdef O_NONBLOCK      
46873 +#ifdef O_NONBLOCK
46874         return fcntl(fd, F_SETFL, O_NONBLOCK | O_RDWR);
46875 +#elif defined _WIN32
46876 +    return ioctlsocket(fd, FIONBIO, &i);
46877  #else
46878         return 0;
46879  #endif
46880 @@ -196,7 +202,7 @@
46881  
46882  int fdevent_event_next_fdndx(fdevents *ev, int ndx) {
46883         if (ev->event_next_fdndx) return ev->event_next_fdndx(ev, ndx);
46884 -       
46885 +
46886         return -1;
46887  }
46888  
46889
46890 Property changes on: src/fdevent.c
46891 ___________________________________________________________________
46892 Name: svn:eol-style
46893    + native
46894
46895
46896 Property changes on: src
46897 ___________________________________________________________________
46898 Name: svn:ignore
46899    - Makefile.in
46900 Makefile
46901 spawn-fcgi
46902 chunk
46903 lemon
46904 lighttpd
46905 *.exe
46906 .deps
46907 .libs
46908 array
46909 mod_ssi_exprparser.c
46910 configparser.c
46911
46912    + Makefile.in
46913 Makefile
46914 spawn-fcgi
46915 chunk
46916 lemon
46917 lighttpd
46918 *.exe
46919 .deps
46920 .libs
46921 array
46922 mod_ssi_exprparser.c
46923 configparser.c
46924 tags
46925 TAGS
46926 *.o
46927 *.i
46928 *.s
46929 proc_open
46930 configparser.h
46931 *.swp
46932
46933
46934
46935 Property changes on: distribute.sh.in
46936 ___________________________________________________________________
46937 Name: svn:eol-style
46938    + native
46939
46940
46941 Property changes on: README
46942 ___________________________________________________________________
46943 Name: svn:eol-style
46944    + native
46945
46946
46947 Property changes on: openwrt/lighttpd.conf
46948 ___________________________________________________________________
46949 Name: svn:eol-style
46950    + native
46951
46952
46953 Property changes on: openwrt/control.in
46954 ___________________________________________________________________
46955 Name: svn:eol-style
46956    + native
46957
46958
46959 Property changes on: openwrt/S51lighttpd
46960 ___________________________________________________________________
46961 Name: svn:eol-style
46962    + native
46963
46964
46965 Property changes on: openwrt/conffiles
46966 ___________________________________________________________________
46967 Name: svn:eol-style
46968    + native
46969
46970
46971 Property changes on: openwrt/Makefile.am
46972 ___________________________________________________________________
46973 Name: svn:eol-style
46974    + native
46975
46976
46977 Property changes on: openwrt/lighttpd.mk.in
46978 ___________________________________________________________________
46979 Name: svn:eol-style
46980    + native
46981
46982
46983 Property changes on: openwrt/.cvsignore
46984 ___________________________________________________________________
46985 Name: svn:eol-style
46986    + native
46987
46988 Index: cygwin/lighttpd.README.in
46989 ===================================================================
46990 --- cygwin/lighttpd.README.in   (.../tags/lighttpd-1.4.11)      (revision 1159)
46991 +++ cygwin/lighttpd.README.in   (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
46992 @@ -1,114 +1,114 @@
46993 -lighttpd\r
46994 -------------------------------------------\r
46995 -A fast, secure and flexible webserver\r
46996 -\r
46997 -Runtime requirements:\r
46998 -  cygwin-1.5.10 or newer\r
46999 -  crypt-1.1 or newer\r
47000 -  libbz2_1-1.0.2 or newer\r
47001 -  libpcre0-4.5 or newer\r
47002 -  openssl-0.9.7d or newer\r
47003 -  zlib-1.2.1 or newer\r
47004 -\r
47005 -Build requirements:\r
47006 -  cygwin-1.5.10 or newer\r
47007 -  gcc-3.3.1-3 or newer\r
47008 -  binutils-20030901-1 or newer\r
47009 -  crypt\r
47010 -  openssl-devel\r
47011 -  openssl\r
47012 -  openldap\r
47013 -  openldap-devel\r
47014 -  zlib\r
47015 -  bzip2\r
47016 -\r
47017 -Canonical homepage:\r
47018 -  http://jan.kneschke.de/projects/lighttpd/\r
47019 -\r
47020 -Canonical download:\r
47021 -  http://jan.kneschke.de/projects/lighttpd/download\r
47022 -\r
47023 -------------------------------------\r
47024 -\r
47025 -Build instructions:\r
47026 -  unpack lighttpd-@VERSION@-<REL>-src.tar.bz2\r
47027 -    if you use setup to install this src package, it will be\r
47028 -        unpacked under /usr/src automatically\r
47029 -  cd /usr/src\r
47030 -  ./lighttpd-@VERSION@-<REL>.sh all\r
47031 -\r
47032 -This will create:\r
47033 -  /usr/src/lighttpd-@VERSION@-<REL>.tar.bz2\r
47034 -  /usr/src/lighttpd-@VERSION@-<REL>-src.tar.bz2\r
47035 -\r
47036 -Or use './lighttpd-@VERSION@-<REL>.sh prep' to get a patched source directory\r
47037 -\r
47038 --------------------------------------------\r
47039 -\r
47040 -Files included in the binary distribution:\r
47041 -\r
47042 -  /etc/lighttpd/lighttpd.conf.default\r
47043 -  /usr/lib/cyglightcomp.dll\r
47044 -  /usr/lib/lighttpd/mod_access.dll\r
47045 -  /usr/lib/lighttpd/mod_accesslog.dll\r
47046 -  /usr/lib/lighttpd/mod_auth.dll\r
47047 -  /usr/lib/lighttpd/mod_cgi.dll\r
47048 -  /usr/lib/lighttpd/mod_compress.dll\r
47049 -  /usr/lib/lighttpd/mod_evhost.dll\r
47050 -  /usr/lib/lighttpd/mod_expire.dll\r
47051 -  /usr/lib/lighttpd/mod_fastcgi.dll\r
47052 -  /usr/lib/lighttpd/mod_httptls.dll\r
47053 -  /usr/lib/lighttpd/mod_maps.dll\r
47054 -  /usr/lib/lighttpd/mod_proxy.dll\r
47055 -  /usr/lib/lighttpd/mod_redirect.dll\r
47056 -  /usr/lib/lighttpd/mod_rewrite.dll\r
47057 -  /usr/lib/lighttpd/mod_rrdtool.dll\r
47058 -  /usr/lib/lighttpd/mod_secdownload.dll\r
47059 -  /usr/lib/lighttpd/mod_simple_vhost.dll\r
47060 -  /usr/lib/lighttpd/mod_ssi.dll\r
47061 -  /usr/lib/lighttpd/mod_status.dll\r
47062 -  /usr/lib/lighttpd/mod_usertrack.dll\r
47063 -  /usr/sbin/lighttpd.exe\r
47064 -  /usr/share/doc/Cygwin/lighttpd-1.3.0.README\r
47065 -  /usr/share/doc/lighttpd-1.3.0/accesslog.txt\r
47066 -  /usr/share/doc/lighttpd-1.3.0/authentification.txt\r
47067 -  /usr/share/doc/lighttpd-1.3.0/AUTHORS\r
47068 -  /usr/share/doc/lighttpd-1.3.0/cgi.txt\r
47069 -  /usr/share/doc/lighttpd-1.3.0/ChangeLog\r
47070 -  /usr/share/doc/lighttpd-1.3.0/compress.txt\r
47071 -  /usr/share/doc/lighttpd-1.3.0/configuration.txt\r
47072 -  /usr/share/doc/lighttpd-1.3.0/COPYING\r
47073 -  /usr/share/doc/lighttpd-1.3.0/fastcgi-state.txt\r
47074 -  /usr/share/doc/lighttpd-1.3.0/fastcgi.txt\r
47075 -  /usr/share/doc/lighttpd-1.3.0/features.txt\r
47076 -  /usr/share/doc/lighttpd-1.3.0/INSTALL\r
47077 -  /usr/share/doc/lighttpd-1.3.0/NEWS\r
47078 -  /usr/share/doc/lighttpd-1.3.0/performance.txt\r
47079 -  /usr/share/doc/lighttpd-1.3.0/plugins.txt\r
47080 -  /usr/share/doc/lighttpd-1.3.0/proxy.txt\r
47081 -  /usr/share/doc/lighttpd-1.3.0/README\r
47082 -  /usr/share/doc/lighttpd-1.3.0/redirect.txt\r
47083 -  /usr/share/doc/lighttpd-1.3.0/rewrite.txt\r
47084 -  /usr/share/doc/lighttpd-1.3.0/rrdtool.txt\r
47085 -  /usr/share/doc/lighttpd-1.3.0/secdownload.txt\r
47086 -  /usr/share/doc/lighttpd-1.3.0/security.txt\r
47087 -  /usr/share/doc/lighttpd-1.3.0/simple-vhost.txt\r
47088 -  /usr/share/doc/lighttpd-1.3.0/skeleton.txt\r
47089 -  /usr/share/doc/lighttpd-1.3.0/ssi.txt\r
47090 -  /usr/share/doc/lighttpd-1.3.0/state.txt\r
47091 -  /usr/share/man/man1/lighttpd.1.gz\r
47092 -\r
47093 -------------------\r
47094 -\r
47095 -Port Notes:\r
47096 -\r
47097 -----------  lighttpd-1.3.1-1 -----------\r
47098 -\r
47099 -Updated to 1.3.1\r
47100 -\r
47101 -----------  lighttpd-1.3.0-1 -----------\r
47102 -Initial release\r
47103 -\r
47104 -Cygwin port maintained by: Jan Kneschke <jan@kneschke.de>\r
47105 -Please address all questions to the Cygwin mailing list at <cygwin@cygwin.com>\r
47106 -\r
47107 +lighttpd
47108 +------------------------------------------
47109 +A fast, secure and flexible webserver
47110 +
47111 +Runtime requirements:
47112 +  cygwin-1.5.10 or newer
47113 +  crypt-1.1 or newer
47114 +  libbz2_1-1.0.2 or newer
47115 +  libpcre0-4.5 or newer
47116 +  openssl-0.9.7d or newer
47117 +  zlib-1.2.1 or newer
47118 +
47119 +Build requirements:
47120 +  cygwin-1.5.10 or newer
47121 +  gcc-3.3.1-3 or newer
47122 +  binutils-20030901-1 or newer
47123 +  crypt
47124 +  openssl-devel
47125 +  openssl
47126 +  openldap
47127 +  openldap-devel
47128 +  zlib
47129 +  bzip2
47130 +
47131 +Canonical homepage:
47132 +  http://jan.kneschke.de/projects/lighttpd/
47133 +
47134 +Canonical download:
47135 +  http://jan.kneschke.de/projects/lighttpd/download
47136 +
47137 +------------------------------------
47138 +
47139 +Build instructions:
47140 +  unpack lighttpd-@VERSION@-<REL>-src.tar.bz2
47141 +    if you use setup to install this src package, it will be
47142 +        unpacked under /usr/src automatically
47143 +  cd /usr/src
47144 +  ./lighttpd-@VERSION@-<REL>.sh all
47145 +
47146 +This will create:
47147 +  /usr/src/lighttpd-@VERSION@-<REL>.tar.bz2
47148 +  /usr/src/lighttpd-@VERSION@-<REL>-src.tar.bz2
47149 +
47150 +Or use './lighttpd-@VERSION@-<REL>.sh prep' to get a patched source directory
47151 +
47152 +-------------------------------------------
47153 +
47154 +Files included in the binary distribution:
47155 +
47156 +  /etc/lighttpd/lighttpd.conf.default
47157 +  /usr/lib/cyglightcomp.dll
47158 +  /usr/lib/lighttpd/mod_access.dll
47159 +  /usr/lib/lighttpd/mod_accesslog.dll
47160 +  /usr/lib/lighttpd/mod_auth.dll
47161 +  /usr/lib/lighttpd/mod_cgi.dll
47162 +  /usr/lib/lighttpd/mod_compress.dll
47163 +  /usr/lib/lighttpd/mod_evhost.dll
47164 +  /usr/lib/lighttpd/mod_expire.dll
47165 +  /usr/lib/lighttpd/mod_fastcgi.dll
47166 +  /usr/lib/lighttpd/mod_httptls.dll
47167 +  /usr/lib/lighttpd/mod_maps.dll
47168 +  /usr/lib/lighttpd/mod_proxy.dll
47169 +  /usr/lib/lighttpd/mod_redirect.dll
47170 +  /usr/lib/lighttpd/mod_rewrite.dll
47171 +  /usr/lib/lighttpd/mod_rrdtool.dll
47172 +  /usr/lib/lighttpd/mod_secdownload.dll
47173 +  /usr/lib/lighttpd/mod_simple_vhost.dll
47174 +  /usr/lib/lighttpd/mod_ssi.dll
47175 +  /usr/lib/lighttpd/mod_status.dll
47176 +  /usr/lib/lighttpd/mod_usertrack.dll
47177 +  /usr/sbin/lighttpd.exe
47178 +  /usr/share/doc/Cygwin/lighttpd-1.3.0.README
47179 +  /usr/share/doc/lighttpd-1.3.0/accesslog.txt
47180 +  /usr/share/doc/lighttpd-1.3.0/authentification.txt
47181 +  /usr/share/doc/lighttpd-1.3.0/AUTHORS
47182 +  /usr/share/doc/lighttpd-1.3.0/cgi.txt
47183 +  /usr/share/doc/lighttpd-1.3.0/ChangeLog
47184 +  /usr/share/doc/lighttpd-1.3.0/compress.txt
47185 +  /usr/share/doc/lighttpd-1.3.0/configuration.txt
47186 +  /usr/share/doc/lighttpd-1.3.0/COPYING
47187 +  /usr/share/doc/lighttpd-1.3.0/fastcgi-state.txt
47188 +  /usr/share/doc/lighttpd-1.3.0/fastcgi.txt
47189 +  /usr/share/doc/lighttpd-1.3.0/features.txt
47190 +  /usr/share/doc/lighttpd-1.3.0/INSTALL
47191 +  /usr/share/doc/lighttpd-1.3.0/NEWS
47192 +  /usr/share/doc/lighttpd-1.3.0/performance.txt
47193 +  /usr/share/doc/lighttpd-1.3.0/plugins.txt
47194 +  /usr/share/doc/lighttpd-1.3.0/proxy.txt
47195 +  /usr/share/doc/lighttpd-1.3.0/README
47196 +  /usr/share/doc/lighttpd-1.3.0/redirect.txt
47197 +  /usr/share/doc/lighttpd-1.3.0/rewrite.txt
47198 +  /usr/share/doc/lighttpd-1.3.0/rrdtool.txt
47199 +  /usr/share/doc/lighttpd-1.3.0/secdownload.txt
47200 +  /usr/share/doc/lighttpd-1.3.0/security.txt
47201 +  /usr/share/doc/lighttpd-1.3.0/simple-vhost.txt
47202 +  /usr/share/doc/lighttpd-1.3.0/skeleton.txt
47203 +  /usr/share/doc/lighttpd-1.3.0/ssi.txt
47204 +  /usr/share/doc/lighttpd-1.3.0/state.txt
47205 +  /usr/share/man/man1/lighttpd.1.gz
47206 +
47207 +------------------
47208 +
47209 +Port Notes:
47210 +
47211 +----------  lighttpd-1.3.1-1 -----------
47212 +
47213 +Updated to 1.3.1
47214 +
47215 +----------  lighttpd-1.3.0-1 -----------
47216 +Initial release
47217 +
47218 +Cygwin port maintained by: Jan Kneschke <jan@kneschke.de>
47219 +Please address all questions to the Cygwin mailing list at <cygwin@cygwin.com>
47220 +
47221
47222 Property changes on: cygwin/lighttpd.README.in
47223 ___________________________________________________________________
47224 Name: svn:eol-style
47225    + native
47226
47227
47228 Property changes on: cygwin/setup.hint
47229 ___________________________________________________________________
47230 Name: svn:eol-style
47231    + native
47232
47233
47234 Property changes on: cygwin/Makefile.am
47235 ___________________________________________________________________
47236 Name: svn:eol-style
47237    + native
47238
47239
47240 Property changes on: cygwin/.cvsignore
47241 ___________________________________________________________________
47242 Name: svn:eol-style
47243    + native
47244
47245
47246 Property changes on: tests/mod-auth.t
47247 ___________________________________________________________________
47248 Name: svn:eol-style
47249    + native
47250
47251
47252 Property changes on: tests/mod-access.t
47253 ___________________________________________________________________
47254 Name: svn:eol-style
47255    + native
47256
47257 Index: tests/bug-12.conf
47258 ===================================================================
47259 --- tests/bug-12.conf   (.../tags/lighttpd-1.4.11)      (revision 1159)
47260 +++ tests/bug-12.conf   (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
47261 @@ -1,5 +1,5 @@
47262 -server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
47263 -server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
47264 +server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
47265 +server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
47266  
47267  ## bind to port (default: 80)
47268  server.port                 = 2048
47269 @@ -8,7 +8,7 @@
47270  
47271  ## bind to localhost (default: all interfaces)
47272  server.bind                = "localhost"
47273 -server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
47274 +server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
47275  server.name                = "www.example.org"
47276  server.tag                 = "Apache 1.3.29"
47277  
47278 @@ -61,7 +61,7 @@
47279  ######################## MODULE CONFIG ############################
47280  
47281  
47282 -accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
47283 +accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
47284  
47285  mimetype.assign             = ( ".png"  => "image/png", 
47286                                  ".jpg"  => "image/jpeg",
47287 @@ -79,7 +79,7 @@
47288                                 ".c"    => "text/plain",
47289                                 ".conf" => "text/plain" )
47290  
47291 -compress.cache-dir          = "@SRCDIR@/tmp/lighttpd/cache/compress/"
47292 +compress.cache-dir          = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
47293  compress.filetype           = ("text/plain", "text/html")
47294  
47295  setenv.add-environment      = ( "TRAC_ENV" => "foo")
47296 @@ -92,7 +92,7 @@
47297                                     "host" => "127.0.0.1",
47298                                     "port" => 1026,
47299  #                                  "mode" => "authorizer",
47300 -#                                  "docroot" => "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/",
47301 +#                                  "docroot" => env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/",
47302                                   )
47303                                 )
47304                               )
47305 @@ -108,7 +108,7 @@
47306  ssl.pemfile                 = "server.pem"
47307  
47308  auth.backend                = "plain"
47309 -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
47310 +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
47311  auth.backend.plain.groupfile = "lighttpd.group"
47312  
47313  auth.backend.ldap.hostname  = "localhost"
47314 @@ -151,15 +151,15 @@
47315  status.config-url           = "/server-config"
47316  
47317  simple-vhost.document-root  = "pages"
47318 -simple-vhost.server-root    = "@SRCDIR@/tmp/lighttpd/servers/"
47319 +simple-vhost.server-root    = env.SRCDIR + "/tmp/lighttpd/servers/"
47320  simple-vhost.default-host   = "www.example.org"
47321  
47322  $HTTP["host"] == "vvv.example.org" {
47323 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
47324 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
47325  }
47326  
47327  $HTTP["host"] == "zzz.example.org" {
47328 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
47329 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
47330    server.name = "zzz.example.org"
47331  }
47332  
47333
47334 Property changes on: tests/bug-12.conf
47335 ___________________________________________________________________
47336 Name: svn:eol-style
47337    + native
47338
47339
47340 Property changes on: tests/mod-secdownload.t
47341 ___________________________________________________________________
47342 Name: svn:eol-style
47343    + native
47344
47345 Index: tests/fastcgi-10.conf
47346 ===================================================================
47347 --- tests/fastcgi-10.conf       (.../tags/lighttpd-1.4.11)      (revision 1159)
47348 +++ tests/fastcgi-10.conf       (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
47349 @@ -1,12 +1,12 @@
47350 -server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
47351 -server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
47352 +server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
47353 +server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
47354  
47355  ## bind to port (default: 80)
47356  server.port                 = 2048
47357  
47358  ## bind to localhost (default: all interfaces)
47359  server.bind                = "localhost"
47360 -server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
47361 +server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
47362  server.name                = "www.example.org"
47363  server.tag                 = "Apache 1.3.29"
47364  
47365 @@ -44,7 +44,7 @@
47366  ######################## MODULE CONFIG ############################
47367  
47368  
47369 -accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
47370 +accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
47371  
47372  mimetype.assign             = ( ".png"  => "image/png", 
47373                                  ".jpg"  => "image/jpeg",
47374 @@ -62,7 +62,7 @@
47375                                 ".c"    => "text/plain",
47376                                 ".conf" => "text/plain" )
47377  
47378 -compress.cache-dir          = "@SRCDIR@/tmp/lighttpd/cache/compress/"
47379 +compress.cache-dir          = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
47380  compress.filetype           = ("text/plain", "text/html")
47381  
47382  fastcgi.debug               = 0
47383 @@ -85,7 +85,7 @@
47384  ssl.pemfile                 = "server.pem"
47385  
47386  auth.backend                = "plain"
47387 -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
47388 +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
47389  auth.backend.plain.groupfile = "lighttpd.group"
47390  
47391  auth.backend.ldap.hostname  = "localhost"
47392 @@ -128,11 +128,11 @@
47393  status.config-url           = "/server-config"
47394  
47395  $HTTP["host"] == "vvv.example.org" {
47396 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
47397 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
47398  }
47399  
47400  $HTTP["host"] == "zzz.example.org" {
47401 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
47402 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
47403    server.name = "zzz.example.org"
47404  }
47405  
47406
47407 Property changes on: tests/fastcgi-10.conf
47408 ___________________________________________________________________
47409 Name: svn:eol-style
47410    + native
47411
47412 Index: tests/bug-06.conf
47413 ===================================================================
47414 --- tests/bug-06.conf   (.../tags/lighttpd-1.4.11)      (revision 1159)
47415 +++ tests/bug-06.conf   (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
47416 @@ -1,5 +1,5 @@
47417 -server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
47418 -server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
47419 +server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
47420 +server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
47421  
47422  ## bind to port (default: 80)
47423  server.port                 = 2048
47424 @@ -8,7 +8,7 @@
47425  
47426  ## bind to localhost (default: all interfaces)
47427  server.bind                = "localhost"
47428 -server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
47429 +server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
47430  server.name                = "www.example.org"
47431  server.tag                 = "Apache 1.3.29"
47432  
47433 @@ -59,7 +59,7 @@
47434  ######################## MODULE CONFIG ############################
47435  
47436  
47437 -accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
47438 +accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
47439  
47440  mimetype.assign             = ( ".png"  => "image/png", 
47441                                  ".jpg"  => "image/jpeg",
47442 @@ -77,7 +77,7 @@
47443                                 ".c"    => "text/plain",
47444                                 ".conf" => "text/plain" )
47445  
47446 -compress.cache-dir          = "@SRCDIR@/tmp/lighttpd/cache/compress/"
47447 +compress.cache-dir          = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
47448  compress.filetype           = ("text/plain", "text/html")
47449  
47450  setenv.add-environment      = ( "TRAC_ENV" => "foo")
47451 @@ -90,7 +90,7 @@
47452                                     "host" => "127.0.0.1",
47453                                     "port" => 1026,
47454  #                                  "mode" => "authorizer",
47455 -#                                  "docroot" => "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/",
47456 +#                                  "docroot" => env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/",
47457                                   )
47458                                 )
47459                               )
47460 @@ -106,7 +106,7 @@
47461  ssl.pemfile                 = "server.pem"
47462  
47463  auth.backend                = "plain"
47464 -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
47465 +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
47466  auth.backend.plain.groupfile = "lighttpd.group"
47467  
47468  auth.backend.ldap.hostname  = "localhost"
47469 @@ -149,15 +149,15 @@
47470  status.config-url           = "/server-config"
47471  
47472  simple-vhost.document-root  = "pages"
47473 -simple-vhost.server-root    = "@SRCDIR@/tmp/lighttpd/servers/"
47474 +simple-vhost.server-root    = env.SRCDIR + "/tmp/lighttpd/servers/"
47475  simple-vhost.default-host   = "www.example.org"
47476  
47477  $HTTP["host"] == "vvv.example.org" {
47478 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
47479 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
47480  }
47481  
47482  $HTTP["host"] == "zzz.example.org" {
47483 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
47484 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
47485    server.name = "zzz.example.org"
47486  }
47487  
47488
47489 Property changes on: tests/bug-06.conf
47490 ___________________________________________________________________
47491 Name: svn:eol-style
47492    + native
47493
47494
47495 Property changes on: tests/core-response.t
47496 ___________________________________________________________________
47497 Name: svn:eol-style
47498    + native
47499
47500 Index: tests/proxy-backend-2.conf
47501 ===================================================================
47502 --- tests/proxy-backend-2.conf  (.../tags/lighttpd-1.4.11)      (revision 0)
47503 +++ tests/proxy-backend-2.conf  (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
47504 @@ -0,0 +1,7 @@
47505 +server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
47506 +server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd-backend-2.pid"
47507 +
47508 +include "default.conf"
47509 +
47510 +
47511 +server.tag = "proxy-backend-2"
47512
47513 Property changes on: tests/proxy-backend-2.conf
47514 ___________________________________________________________________
47515 Name: svn:eol-style
47516    + native
47517
47518
47519 Property changes on: tests/request.t
47520 ___________________________________________________________________
47521 Name: svn:eol-style
47522    + native
47523
47524
47525 Property changes on: tests/mod-userdir.t
47526 ___________________________________________________________________
47527 Name: svn:eol-style
47528    + native
47529
47530 Index: tests/core-keepalive.t
47531 ===================================================================
47532 --- tests/core-keepalive.t      (.../tags/lighttpd-1.4.11)      (revision 1159)
47533 +++ tests/core-keepalive.t      (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
47534 @@ -40,7 +40,7 @@
47535  
47536  GET /12345.txt HTTP/1.0
47537  Host: 123.example.org
47538 -Connection: keep-alive
47539 +Connection: close
47540  EOF
47541   );
47542  $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } , { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
47543
47544 Property changes on: tests/core-keepalive.t
47545 ___________________________________________________________________
47546 Name: svn:eol-style
47547    + native
47548
47549 Index: tests/var-include.conf
47550 ===================================================================
47551 --- tests/var-include.conf      (.../tags/lighttpd-1.4.11)      (revision 1159)
47552 +++ tests/var-include.conf      (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
47553 @@ -2,15 +2,15 @@
47554  debug.log-request-handling = "enable"
47555  debug.log-condition-handling = "enable"
47556  
47557 -server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
47558 -server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
47559 +server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
47560 +server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
47561  
47562  ## bind to port (default: 80)
47563  server.port                 = 2048
47564  
47565  ## bind to localhost (default: all interfaces)
47566  server.bind                = "localhost"
47567 -server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
47568 +server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
47569  server.name                = "www.example.org"
47570  server.tag                 = "Apache 1.3.29"
47571  
47572 @@ -21,19 +21,19 @@
47573  ######################## MODULE CONFIG ############################
47574  
47575  
47576 -accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
47577 +accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
47578  
47579  mimetype.assign             = ( ".html" => "text/html" )
47580  
47581  url.redirect = ("^" => "/default")
47582  
47583  $HTTP["host"] == "www.example.org" {
47584 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
47585 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
47586    server.name = "www.example.org"
47587    url.redirect = ("^" => "/redirect")
47588  }
47589  $HTTP["host"] == "test.example.org" {
47590 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
47591 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
47592    server.name = "test.example.org"
47593    var.myvar = "good"
47594    var.one = 1
47595
47596 Property changes on: tests/var-include.conf
47597 ___________________________________________________________________
47598 Name: svn:eol-style
47599    + native
47600
47601
47602 Property changes on: tests/cleanup.sh
47603 ___________________________________________________________________
47604 Name: svn:eol-style
47605    + native
47606
47607 Index: tests/mod-proxy.t
47608 ===================================================================
47609 --- tests/mod-proxy.t   (.../tags/lighttpd-1.4.11)      (revision 1159)
47610 +++ tests/mod-proxy.t   (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
47611 @@ -8,11 +8,12 @@
47612  
47613  use strict;
47614  use IO::Socket;
47615 -use Test::More tests => 6;
47616 +use Test::More tests => 21;
47617  use LightyTest;
47618  
47619 -my $tf_real = LightyTest->new();
47620  my $tf_proxy = LightyTest->new();
47621 +my $tf_backend1 = LightyTest->new();
47622 +my $tf_backend2 = LightyTest->new();
47623  
47624  my $t;
47625  
47626 @@ -20,18 +21,25 @@
47627  ## 1. the real webserver
47628  ## 2. the proxy server
47629  
47630 -$tf_real->{PORT} = 2048;
47631 -$tf_real->{CONFIGFILE} = 'lighttpd.conf';
47632 -$tf_real->{LIGHTTPD_PIDFILE} = $tf_real->{SRCDIR}.'/tmp/lighttpd/lighttpd.pid';
47633 -
47634 -$tf_proxy->{PORT} = 2050;
47635 +$tf_proxy->{PORT} = 2048;
47636  $tf_proxy->{CONFIGFILE} = 'proxy.conf';
47637  $tf_proxy->{LIGHTTPD_PIDFILE} = $tf_proxy->{SRCDIR}.'/tmp/lighttpd/lighttpd-proxy.pid';
47638  
47639 -ok($tf_real->start_proc == 0, "Starting lighttpd") or die();
47640 +$tf_backend1->{PORT} = 2050;
47641 +$tf_backend1->{CONFIGFILE} = 'proxy-backend-1.conf';
47642 +$tf_backend1->{LIGHTTPD_PIDFILE} = $tf_backend1->{SRCDIR}.'/tmp/lighttpd/lighttpd-backend-1.pid';
47643  
47644 +$tf_backend2->{PORT} = 2051;
47645 +$tf_backend2->{CONFIGFILE} = 'proxy-backend-2.conf';
47646 +$tf_backend2->{LIGHTTPD_PIDFILE} = $tf_backend2->{SRCDIR}.'/tmp/lighttpd/lighttpd-backend-2.pid';
47647 +
47648 +
47649 +ok($tf_backend1->start_proc == 0, "Starting lighttpd") or die();
47650 +
47651  ok($tf_proxy->start_proc == 0, "Starting lighttpd as proxy") or die();
47652  
47653 +sleep(1);
47654 +
47655  $t->{REQUEST}  = ( <<EOF
47656  GET /index.html HTTP/1.0
47657  Host: www.example.org
47658 @@ -45,9 +53,121 @@
47659  Host: www.example.org
47660  EOF
47661   );
47662 -$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'Server' => 'Apache 1.3.29' } ];
47663 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'Server' => 'proxy-backend-1' } ];
47664  ok($tf_proxy->handle_http($t) == 0, 'drop Server from real server');
47665  
47666 +$t->{REQUEST}  = ( <<EOF
47667 +GET /balance-rr/foo HTTP/1.0
47668 +Host: www.example.org
47669 +EOF
47670 + );
47671 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-1' } ];
47672 +ok($tf_proxy->handle_http($t) == 0, 'balance rr - one backend');
47673 +
47674 +$t->{REQUEST}  = ( <<EOF
47675 +GET /balance-rr/foo HTTP/1.0
47676 +Host: www.example.org
47677 +EOF
47678 + );
47679 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-1' } ];
47680 +ok($tf_proxy->handle_http($t) == 0, 'balance rr - one host down, failover');
47681 +
47682 +$t->{REQUEST}  = ( <<EOF
47683 +GET /balance-fair/foo HTTP/1.0
47684 +Host: www.example.org
47685 +EOF
47686 + );
47687 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-1' } ];
47688 +ok($tf_proxy->handle_http($t) == 0, 'balance fair - one backend');
47689 +
47690 +## backend 2 starting 
47691 +ok($tf_backend2->start_proc == 0, "Starting second proxy backend") or die();
47692 +
47693 +$t->{REQUEST}  = ( <<EOF
47694 +GET /balance-rr/foo HTTP/1.0
47695 +Host: www.example.org
47696 +EOF
47697 + );
47698 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ];
47699 +ok($tf_proxy->handle_http($t) == 0, 'balance rr - lb, backend 1');
47700 +
47701 +$t->{REQUEST}  = ( <<EOF
47702 +GET /balance-rr/foo HTTP/1.0
47703 +Host: www.example.org
47704 +EOF
47705 + );
47706 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-1' } ];
47707 +ok($tf_proxy->handle_http($t) == 0, 'balance rr - lb, backend 2');
47708 +
47709 +$t->{REQUEST}  = ( <<EOF
47710 +GET /balance-hash/foo HTTP/1.0
47711 +Host: www.example.org
47712 +EOF
47713 + );
47714 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-1' } ];
47715 +ok($tf_proxy->handle_http($t) == 0, 'balance hash - lb, backend 1');
47716 +
47717 +$t->{REQUEST}  = ( <<EOF
47718 +GET /balance-hash/foo HTTP/1.0
47719 +Host: www.example.org
47720 +EOF
47721 + );
47722 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-1' } ];
47723 +ok($tf_proxy->handle_http($t) == 0, 'balance hash - lb, backend 1 - same URL');
47724 +
47725 +$t->{REQUEST}  = ( <<EOF
47726 +GET /balance-hash/bar HTTP/1.0
47727 +Host: www.example.org
47728 +EOF
47729 + );
47730 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ];
47731 +ok($tf_proxy->handle_http($t) == 0, 'balance hash - lb, backend 2');
47732 +
47733 +$t->{REQUEST}  = ( <<EOF
47734 +GET /balance-hash/bar HTTP/1.0
47735 +Host: www.example.org
47736 +EOF
47737 + );
47738 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ];
47739 +ok($tf_proxy->handle_http($t) == 0, 'balance hash - lb, backend 2 - same URL');
47740 +
47741 +## backend 1 stopping, failover 
47742 +ok($tf_backend1->stop_proc == 0, "Stopping backend 1");
47743 +
47744 +$t->{REQUEST}  = ( <<EOF
47745 +GET /balance-hash/foo HTTP/1.0
47746 +Host: www.example.org
47747 +EOF
47748 + );
47749 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ];
47750 +ok($tf_proxy->handle_http($t) == 0, 'balance hash - failover to backend 2');
47751 +
47752 +$t->{REQUEST}  = ( <<EOF
47753 +GET /balance-hash/bar HTTP/1.0
47754 +Host: www.example.org
47755 +EOF
47756 + );
47757 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ];
47758 +ok($tf_proxy->handle_http($t) == 0, 'balance hash - failover to backend 2 - same URL');
47759 +
47760 +$t->{REQUEST}  = ( <<EOF
47761 +GET /balance-rr/foo HTTP/1.0
47762 +Host: www.example.org
47763 +EOF
47764 + );
47765 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ];
47766 +ok($tf_proxy->handle_http($t) == 0, 'balance rr - failover to backend 2');
47767 +
47768 +$t->{REQUEST}  = ( <<EOF
47769 +GET /balance-fair/foo HTTP/1.0
47770 +Host: www.example.org
47771 +EOF
47772 + );
47773 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 404, 'Server' => 'proxy-backend-2' } ];
47774 +ok($tf_proxy->handle_http($t) == 0, 'balance fair - failover to backend 2');
47775 +
47776 +
47777 +ok($tf_backend2->stop_proc == 0, "Stopping lighttpd");
47778 +
47779  ok($tf_proxy->stop_proc == 0, "Stopping lighttpd proxy");
47780  
47781 -ok($tf_real->stop_proc == 0, "Stopping lighttpd");
47782
47783 Property changes on: tests/mod-proxy.t
47784 ___________________________________________________________________
47785 Name: svn:eol-style
47786    + native
47787
47788
47789 Property changes on: tests/core-var-include.t
47790 ___________________________________________________________________
47791 Name: svn:eol-style
47792    + native
47793
47794 Index: tests/lowercase.conf
47795 ===================================================================
47796 --- tests/lowercase.conf        (.../tags/lighttpd-1.4.11)      (revision 1159)
47797 +++ tests/lowercase.conf        (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
47798 @@ -1,12 +1,12 @@
47799 -server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
47800 -server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
47801 +server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
47802 +server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
47803  
47804  ## bind to port (default: 80)
47805  server.port                 = 2048
47806  
47807  ## bind to localhost (default: all interfaces)
47808  server.bind                = "localhost"
47809 -server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
47810 +server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
47811  
47812  server.force-lowercase-filenames = "enable"
47813  
47814 @@ -57,9 +57,9 @@
47815                                 ".py"  => "/usr/bin/python" )
47816                         
47817  auth.backend                = "plain"
47818 -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
47819 +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
47820  
47821 -auth.backend.htpasswd.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.htpasswd"
47822 +auth.backend.htpasswd.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.htpasswd"
47823  
47824  $HTTP["host"] == "lowercase-auth" {
47825    auth.require             = ( "/image.jpg" => 
47826
47827 Property changes on: tests/lowercase.conf
47828 ___________________________________________________________________
47829 Name: svn:eol-style
47830    + native
47831
47832 Index: tests/condition.conf
47833 ===================================================================
47834 --- tests/condition.conf        (.../tags/lighttpd-1.4.11)      (revision 1159)
47835 +++ tests/condition.conf        (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
47836 @@ -2,15 +2,15 @@
47837  debug.log-request-handling = "enable"
47838  debug.log-condition-handling = "enable"
47839  
47840 -server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
47841 -server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
47842 +server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
47843 +server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
47844  
47845  ## bind to port (default: 80)
47846  server.port                 = 2048
47847  
47848  ## bind to localhost (default: all interfaces)
47849  server.bind                = "localhost"
47850 -server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
47851 +server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
47852  server.name                = "www.example.org"
47853  server.tag                 = "Apache 1.3.29"
47854  
47855 @@ -22,25 +22,25 @@
47856  ######################## MODULE CONFIG ############################
47857  
47858  
47859 -accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
47860 +accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
47861  
47862  mimetype.assign             = ( ".html" => "text/html" )
47863  
47864  url.redirect = ("^" => "/default")
47865  
47866  $HTTP["host"] == "www.example.org" {
47867 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
47868 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
47869    server.name = "www.example.org"
47870    url.redirect = ("^" => "/match_1")
47871  }
47872  else $HTTP["host"] == "test1.example.org" {
47873 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
47874 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
47875    server.name = "test1.example.org"
47876    url.redirect = ("^" => "/match_2")
47877  }
47878  # comments
47879  else $HTTP["host"] == "test2.example.org" {
47880 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
47881 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
47882    server.name = "test2.example.org"
47883    url.redirect = ("^" => "/match_3")
47884  }
47885 @@ -48,7 +48,7 @@
47886          # comments
47887  
47888  else $HTTP["host"] == "test3.example.org" {
47889 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
47890 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
47891    server.name = "test3.example.org"
47892    url.redirect = ("^" => "/match_4")
47893  
47894
47895 Property changes on: tests/condition.conf
47896 ___________________________________________________________________
47897 Name: svn:eol-style
47898    + native
47899
47900
47901 Property changes on: tests/lighttpd.htpasswd
47902 ___________________________________________________________________
47903 Name: svn:eol-style
47904    + native
47905
47906
47907 Property changes on: tests/.cvsignore
47908 ___________________________________________________________________
47909 Name: svn:eol-style
47910    + native
47911
47912
47913 Property changes on: tests/core-request.t
47914 ___________________________________________________________________
47915 Name: svn:eol-style
47916    + native
47917
47918
47919 Property changes on: tests/mod-redirect.t
47920 ___________________________________________________________________
47921 Name: svn:eol-style
47922    + native
47923
47924
47925 Property changes on: tests/mod-cgi.t
47926 ___________________________________________________________________
47927 Name: svn:eol-style
47928    + native
47929
47930
47931 Property changes on: tests/mod-setenv.t
47932 ___________________________________________________________________
47933 Name: svn:eol-style
47934    + native
47935
47936 Index: tests/cachable.t
47937 ===================================================================
47938 --- tests/cachable.t    (.../tags/lighttpd-1.4.11)      (revision 0)
47939 +++ tests/cachable.t    (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
47940 @@ -0,0 +1,112 @@
47941 +#!/usr/bin/env perl
47942 +BEGIN {
47943 +    # add current source dir to the include-path
47944 +    # we need this for make distcheck
47945 +   (my $srcdir = $0) =~ s#/[^/]+$#/#;
47946 +   unshift @INC, $srcdir;
47947 +}
47948 +
47949 +use strict;
47950 +use IO::Socket;
47951 +use Test::More tests => 12;
47952 +use LightyTest;
47953 +
47954 +my $tf = LightyTest->new();
47955 +my $t;
47956 +
47957 +$tf->{CONFIGFILE} = 'lighttpd.conf';
47958 +    
47959 +ok($tf->start_proc == 0, "Starting lighttpd") or die();
47960 +
47961 +## check if If-Modified-Since, If-None-Match works
47962 +
47963 +$t->{REQUEST}  = ( <<EOF
47964 +GET / HTTP/1.0
47965 +If-Modified-Since: Sun, 01 Jan 1970 00:00:01 GMT
47966 +EOF
47967 + );
47968 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
47969 +ok($tf->handle_http($t) == 0, 'Conditional GET - old If-Modified-Since');
47970 +
47971 +$t->{REQUEST}  = ( <<EOF
47972 +GET / HTTP/1.0
47973 +If-Modified-Since: Sun, 01 Jan 1970 00:00:01 GMT; foo
47974 +EOF
47975 + );
47976 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
47977 +ok($tf->handle_http($t) == 0, 'Conditional GET - old If-Modified-Since, comment');
47978 +
47979 +my $now = $t->{date};
47980 +
47981 +$t->{REQUEST}  = ( <<EOF
47982 +GET / HTTP/1.0
47983 +If-Modified-Since: $now
47984 +EOF
47985 + );
47986 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 304 } ];
47987 +ok($tf->handle_http($t) == 0, 'Conditional GET - new If-Modified-Since');
47988 +
47989 +$t->{REQUEST}  = ( <<EOF
47990 +GET / HTTP/1.0
47991 +If-Modified-Since: $now; foo
47992 +EOF
47993 + );
47994 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 304 } ];
47995 +ok($tf->handle_http($t) == 0, 'Conditional GET - new If-Modified-Since, comment');
47996 +
47997 +$t->{REQUEST}  = ( <<EOF
47998 +GET / HTTP/1.0
47999 +If-None-Match: foo
48000 +EOF
48001 + );
48002 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
48003 +ok($tf->handle_http($t) == 0, 'Conditional GET - old If-None-Match');
48004 +
48005 +my $etag = $t->{etag};
48006 +
48007 +$t->{REQUEST}  = ( <<EOF
48008 +GET / HTTP/1.0
48009 +If-None-Match: $etag
48010 +EOF
48011 + );
48012 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 304 } ];
48013 +ok($tf->handle_http($t) == 0, 'Conditional GET - old If-None-Match');
48014 +
48015 +$t->{REQUEST}  = ( <<EOF
48016 +GET / HTTP/1.0
48017 +If-None-Match: $etag
48018 +If-Modified-Since: Sun, 01 Jan 1970 00:00:01 GMT; foo
48019 +EOF
48020 + );
48021 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
48022 +ok($tf->handle_http($t) == 0, 'Conditional GET - ETag + old Last-Modified');
48023 +
48024 +$t->{REQUEST}  = ( <<EOF
48025 +GET / HTTP/1.0
48026 +If-None-Match: $etag
48027 +If-Modified-Since: $now; foo
48028 +EOF
48029 + );
48030 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 304 } ];
48031 +ok($tf->handle_http($t) == 0, 'Conditional GET - ETag, Last-Modified + comment');
48032 +
48033 +$t->{REQUEST}  = ( <<EOF
48034 +GET / HTTP/1.0
48035 +If-None-Match: Foo
48036 +If-Modified-Since: Sun, 01 Jan 1970 00:00:01 GMT; foo
48037 +EOF
48038 + );
48039 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200 } ];
48040 +ok($tf->handle_http($t) == 0, 'Conditional GET - old ETAG + old Last-Modified');
48041 +
48042 +$t->{REQUEST}  = ( <<EOF
48043 +GET / HTTP/1.0
48044 +If-None-Match: $etag
48045 +If-Modified-Since: $now foo
48046 +EOF
48047 + );
48048 +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 412 } ];
48049 +ok($tf->handle_http($t) == 0, 'Conditional GET - ETag + Last-Modified + overlong timestamp');
48050 +
48051 +ok($tf->stop_proc == 0, "Stopping lighttpd");
48052 +
48053
48054 Property changes on: tests/cachable.t
48055 ___________________________________________________________________
48056 Name: svn:executable
48057    + *
48058 Name: svn:eol-style
48059    + native
48060
48061
48062 Property changes on: tests/var-include-sub.conf
48063 ___________________________________________________________________
48064 Name: svn:eol-style
48065    + native
48066
48067 Index: tests/fastcgi-13.conf
48068 ===================================================================
48069 --- tests/fastcgi-13.conf       (.../tags/lighttpd-1.4.11)      (revision 1159)
48070 +++ tests/fastcgi-13.conf       (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
48071 @@ -1,5 +1,5 @@
48072 -server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48073 -server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
48074 +server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48075 +server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
48076  
48077  debug.log-request-header   = "enable"
48078  debug.log-response-header  = "enable"
48079 @@ -10,7 +10,7 @@
48080  
48081  ## bind to localhost (default: all interfaces)
48082  server.bind                = "localhost"
48083 -server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
48084 +server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
48085  server.name                = "www.example.org"
48086  server.tag                 = "Apache 1.3.29"
48087  
48088 @@ -59,7 +59,7 @@
48089  ######################## MODULE CONFIG ############################
48090  
48091  
48092 -accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
48093 +accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
48094  
48095  mimetype.assign             = ( ".png"  => "image/png", 
48096                                  ".jpg"  => "image/jpeg",
48097 @@ -77,7 +77,7 @@
48098                                 ".c"    => "text/plain",
48099                                 ".conf" => "text/plain" )
48100  
48101 -compress.cache-dir          = "@SRCDIR@/tmp/lighttpd/cache/compress/"
48102 +compress.cache-dir          = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
48103  compress.filetype           = ("text/plain", "text/html")
48104  
48105  fastcgi.debug               = 0
48106 @@ -102,7 +102,7 @@
48107  ssl.pemfile                 = "server.pem"
48108  
48109  auth.backend                = "plain"
48110 -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
48111 +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
48112  auth.backend.plain.groupfile = "lighttpd.group"
48113  
48114  auth.backend.ldap.hostname  = "localhost"
48115 @@ -145,11 +145,11 @@
48116  status.config-url           = "/server-config"
48117  
48118  $HTTP["host"] == "vvv.example.org" {
48119 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48120 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48121  }
48122  
48123  $HTTP["host"] == "zzz.example.org" {
48124 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48125 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48126    server.name = "zzz.example.org"
48127  }
48128  
48129
48130 Property changes on: tests/fastcgi-13.conf
48131 ___________________________________________________________________
48132 Name: svn:eol-style
48133    + native
48134
48135
48136 Property changes on: tests/lowercase.t
48137 ___________________________________________________________________
48138 Name: svn:eol-style
48139    + native
48140
48141
48142 Property changes on: tests/SConscript
48143 ___________________________________________________________________
48144 Name: svn:eol-style
48145    + native
48146
48147 Index: tests/fcgi-responder.c
48148 ===================================================================
48149 --- tests/fcgi-responder.c      (.../tags/lighttpd-1.4.11)      (revision 1159)
48150 +++ tests/fcgi-responder.c      (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
48151 @@ -6,11 +6,17 @@
48152  int main () {
48153         int num_requests = 2;
48154         
48155 -       while (num_requests > 0 &&
48156 -              FCGI_Accept() >= 0) {
48157 -               char* p;
48158 -               
48159 -               if (NULL != (p = getenv("QUERY_STRING"))) {
48160 +       while (num_requests > 0 && FCGI_Accept() >= 0) {
48161 +               char* p = NULL;
48162 +               char* doc_root = NULL;
48163 +               char fname[4096];
48164 +               char* pfname = (char *)fname;
48165 +
48166 +               doc_root = getenv("DOCUMENT_ROOT");
48167 +               p = getenv("QUERY_STRING");
48168 +
48169 +               if (NULL != p && NULL != doc_root) {
48170 +                       snprintf(pfname, sizeof(fname), "%s/phpinfo.php", doc_root);
48171                         if (0 == strcmp(p, "lf")) {
48172                                 printf("Status: 200 OK\n\n");
48173                         } else if (0 == strcmp(p, "crlf")) {
48174 @@ -23,6 +29,18 @@
48175                                 printf("Status: 200 OK\r\n");
48176                                 fflush(stdout);
48177                                 printf("\r\n");
48178 +                       } else if (0 == strcmp(p,"x-lighttpd-send-file")) {
48179 +                               printf("Status: 200 OK\r\n");
48180 +                               printf("X-LIGHTTPD-send-file: %s\r\n", pfname);
48181 +                               printf("\r\n");
48182 +                       } else if (0 == strcmp(p,"xsendfile")) {
48183 +                               printf("Status: 200 OK\r\n");
48184 +                               printf("X-Sendfile: %s\r\n", pfname);
48185 +                               printf("\r\n");
48186 +                       } else if (0 == strcmp(p,"xsendfile-mixed-case")) {
48187 +                               printf("Status: 200 OK\r\n");
48188 +                               printf("X-SeNdFiLe: %s\r\n", pfname);
48189 +                               printf("\r\n");
48190                         } else if (0 == strcmp(p, "die-at-end")) {
48191                                 printf("Status: 200 OK\r\n\r\n");
48192                                 num_requests--;
48193
48194 Property changes on: tests/fcgi-responder.c
48195 ___________________________________________________________________
48196 Name: svn:eol-style
48197    + native
48198
48199
48200 Property changes on: tests/fcgi-auth.c
48201 ___________________________________________________________________
48202 Name: svn:eol-style
48203    + native
48204
48205 Index: tests/proxy-backend-1.conf
48206 ===================================================================
48207 --- tests/proxy-backend-1.conf  (.../tags/lighttpd-1.4.11)      (revision 0)
48208 +++ tests/proxy-backend-1.conf  (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
48209 @@ -0,0 +1,7 @@
48210 +server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48211 +server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd-backend-1.pid"
48212 +
48213 +include "default.conf"
48214 +
48215 +
48216 +server.tag = "proxy-backend-1"
48217
48218 Property changes on: tests/proxy-backend-1.conf
48219 ___________________________________________________________________
48220 Name: svn:eol-style
48221    + native
48222
48223
48224 Property changes on: tests/wrapper.sh
48225 ___________________________________________________________________
48226 Name: svn:eol-style
48227    + native
48228
48229
48230 Property changes on: tests/core.t
48231 ___________________________________________________________________
48232 Name: svn:eol-style
48233    + native
48234
48235
48236 Property changes on: tests/lighttpd.user
48237 ___________________________________________________________________
48238 Name: svn:eol-style
48239    + native
48240
48241 Index: tests/mod-fastcgi.t
48242 ===================================================================
48243 --- tests/mod-fastcgi.t (.../tags/lighttpd-1.4.11)      (revision 1159)
48244 +++ tests/mod-fastcgi.t (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
48245 @@ -7,7 +7,7 @@
48246  }
48247  
48248  use strict;
48249 -use Test::More tests => 47;
48250 +use Test::More tests => 49;
48251  use LightyTest;
48252  
48253  my $tf = LightyTest->new();
48254 @@ -15,7 +15,7 @@
48255  my $t;
48256  
48257  SKIP: {
48258 -       skip "no PHP running on port 1026", 30 unless $tf->listening_on(1026);
48259 +       skip "no PHP running on port 1026", 29 unless $tf->listening_on(1026);
48260  
48261         ok($tf->start_proc == 0, "Starting lighttpd") or die();
48262  
48263 @@ -223,7 +223,7 @@
48264  }
48265  
48266  SKIP: {
48267 -       skip "no php found", 4 unless -x "/home/jan/Documents/php-5.1.0/sapi/cgi/php"; 
48268 +       skip "no php found", 4 unless -x "/home/jan/Documents/php-5.1.0/sapi/cgi/php";
48269         $tf->{CONFIGFILE} = 'fastcgi-13.conf';
48270         ok($tf->start_proc == 0, "Starting lighttpd with $tf->{CONFIGFILE}") or die();
48271         $t->{REQUEST}  = ( <<EOF
48272 @@ -285,7 +285,35 @@
48273         $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => 'test123' } ];
48274         ok($tf->handle_http($t) == 0, 'line-ending \r\n + \r\n');
48275  
48276 +    # X-LIGHTTPD-send-file
48277         $t->{REQUEST}  = ( <<EOF
48278 +GET /index.fcgi?x-lighttpd-send-file HTTP/1.0
48279 +Host: www.example.org
48280 +EOF
48281 + );
48282 +       $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '<?php phpinfo(); ?>
48283 +' } ];
48284 +       ok($tf->handle_http($t) == 0, 'X-LIGHTTPD-send-file');
48285 +    # X-Sendfile
48286 +       $t->{REQUEST}  = ( <<EOF
48287 +GET /index.fcgi?xsendfile HTTP/1.0
48288 +Host: www.example.org
48289 +EOF
48290 + );
48291 +       $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '<?php phpinfo(); ?>
48292 +' } ];
48293 +       ok($tf->handle_http($t) == 0, 'X-Sendfile');
48294 +
48295 +       $t->{REQUEST}  = ( <<EOF
48296 +GET /index.fcgi?xsendfile-mixed-case HTTP/1.0
48297 +Host: www.example.org
48298 +EOF
48299 + );
48300 +       $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'HTTP-Content' => '<?php phpinfo(); ?>
48301 +' } ];
48302 +       ok($tf->handle_http($t) == 0, 'X-SeNdFiLe in mixed case');
48303 +
48304 +       $t->{REQUEST}  = ( <<EOF
48305  GET /index.fcgi?die-at-end HTTP/1.0
48306  Host: www.example.org
48307  EOF
48308
48309 Property changes on: tests/mod-fastcgi.t
48310 ___________________________________________________________________
48311 Name: svn:eol-style
48312    + native
48313
48314
48315 Property changes on: tests/mod-rewrite.t
48316 ___________________________________________________________________
48317 Name: svn:eol-style
48318    + native
48319
48320 Index: tests/lighttpd.conf
48321 ===================================================================
48322 --- tests/lighttpd.conf (.../tags/lighttpd-1.4.11)      (revision 1159)
48323 +++ tests/lighttpd.conf (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
48324 @@ -1,81 +1,19 @@
48325 -debug.log-request-handling = "enable"
48326 -debug.log-condition-handling = "enable"
48327 -server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48328 -server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
48329 +server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48330 +server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
48331 +server.tag = "Apache 1.3.29"
48332  
48333  ## 64 Mbyte ... nice limit
48334  server.max-request-size = 65000
48335  
48336 -## bind to port (default: 80)
48337 -server.port                 = 2048
48338 +include "default.conf"
48339  
48340 -## bind to localhost (default: all interfaces)
48341 -server.bind                = "localhost"
48342 -server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
48343 -server.name                = "www.example.org"
48344 -server.tag                 = "Apache 1.3.29"
48345 +setenv.add-request-header   = ( "FOO" => "foo")
48346 +setenv.add-response-header  = ( "BAR" => "foo")
48347  
48348 -server.dir-listing          = "enable"
48349 -
48350 -#server.event-handler        = "linux-sysepoll"
48351 -#server.event-handler        = "linux-rtsig"
48352 -
48353 -#server.modules.path         = ""
48354 -server.modules              = ( 
48355 -                               "mod_rewrite",
48356 -                               "mod_setenv",
48357 -                               "mod_secdownload",
48358 -                               "mod_access", 
48359 -                               "mod_auth",
48360 -#                              "mod_httptls",
48361 -                               "mod_status", 
48362 -                               "mod_expire",
48363 -                               "mod_simple_vhost",
48364 -                               "mod_redirect", 
48365 -#                              "mod_evhost",
48366 -#                              "mod_localizer",
48367 -                               "mod_fastcgi",
48368 -                               "mod_cgi",
48369 -                               "mod_compress",
48370 -                               "mod_userdir",
48371 -                               "mod_ssi",
48372 -                               "mod_accesslog" ) 
48373 -
48374 -server.indexfiles           = ( "index.php", "index.html", 
48375 -                                "index.htm", "default.htm" )
48376 -
48377 -
48378 -######################## MODULE CONFIG ############################
48379 -
48380 -ssi.extension = ( ".shtml" )
48381 -
48382 -accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
48383 -
48384 -mimetype.assign             = ( ".png"  => "image/png", 
48385 -                                ".jpg"  => "image/jpeg",
48386 -                                ".jpeg" => "image/jpeg",
48387 -                                ".gif"  => "image/gif",
48388 -                                ".html" => "text/html",
48389 -                                ".htm"  => "text/html",
48390 -                                ".pdf"  => "application/pdf",
48391 -                                ".swf"  => "application/x-shockwave-flash",
48392 -                                ".spl"  => "application/futuresplash",
48393 -                                ".txt"  => "text/plain",
48394 -                                ".tar.gz" =>   "application/x-tgz",
48395 -                                ".tgz"  => "application/x-tgz",
48396 -                                ".gz"   => "application/x-gzip",
48397 -                               ".c"    => "text/plain",
48398 -                               ".conf" => "text/plain" )
48399 -
48400  $HTTP["host"] == "cache.example.org" {
48401 -  compress.cache-dir          = "@SRCDIR@/tmp/lighttpd/cache/compress/"
48402 +  compress.cache-dir          = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
48403  }
48404 -compress.filetype           = ("text/plain", "text/html")
48405  
48406 -setenv.add-environment      = ( "TRAC_ENV" => "tracenv", "SETENV" => "setenv")
48407 -setenv.add-request-header   = ( "FOO" => "foo")
48408 -setenv.add-response-header  = ( "BAR" => "foo")
48409 -
48410  $HTTP["url"] =~ "\.pdf$" {
48411    server.range-requests = "disable"
48412  }
48413 @@ -85,76 +23,31 @@
48414                                 "/prefix.fcgi" => ( ( "host" => "127.0.0.1", "port" => 1026, "check-local" => "disable", "broken-scriptfilename" => "enable" ) )
48415                               )
48416                 
48417 -
48418 -cgi.assign                  = ( ".pl"  => "/usr/bin/perl",
48419 -                                ".cgi" => "/usr/bin/perl",
48420 -                               ".py"  => "/usr/bin/python" )
48421 -                       
48422 -userdir.include-user = ( "jan" )
48423 -userdir.path = "/"
48424 -
48425 -ssl.engine                  = "disable"
48426 -ssl.pemfile                 = "server.pem"
48427 -
48428  $HTTP["host"] == "auth-htpasswd.example.org" {
48429         auth.backend                = "htpasswd"
48430  }
48431  
48432 -auth.backend                = "plain"
48433 -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
48434 -
48435 -auth.backend.htpasswd.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.htpasswd"
48436 -
48437 -
48438 -auth.require                = ( "/server-status" => 
48439 -                                ( 
48440 -                                 "method"  => "digest",
48441 -                                 "realm"   => "download archiv",
48442 -                                 "require" => "group=www|user=jan|host=192.168.2.10"
48443 -                               ),
48444 -                               "/server-config" => 
48445 -                                ( 
48446 -                                 "method"  => "basic",
48447 -                                 "realm"   => "download archiv",
48448 -                                 "require" => "valid-user"
48449 -                               )
48450 -                              )
48451 -
48452 -url.access-deny             = ( "~", ".inc")
48453 -
48454 -url.rewrite                = ( "^/rewrite/foo($|\?.+)" => "/indexfile/rewrite.php$1",
48455 -                               "^/rewrite/bar(?:$|\?(.+))" => "/indexfile/rewrite.php?bar&$1" )
48456 -
48457 -expire.url                  = ( "/expire/access" => "access 2 hours", 
48458 -                               "/expire/modification" => "access plus 1 seconds 2 minutes")
48459 -
48460 -#cache.cache-dir             = "/home/weigon/wwwroot/cache/"
48461 -
48462 -#### status module
48463 -status.status-url           = "/server-status"
48464 -status.config-url           = "/server-config"
48465 -
48466  $HTTP["host"] == "vvv.example.org" {
48467 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48468 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48469    secdownload.secret          = "verysecret"
48470 -  secdownload.document-root   = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48471 +  secdownload.document-root   = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48472    secdownload.uri-prefix      = "/sec/"
48473    secdownload.timeout         = 120
48474  }
48475  
48476  $HTTP["host"] == "zzz.example.org" {
48477 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48478 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48479    server.name = "zzz.example.org"
48480  }
48481  
48482  $HTTP["host"] == "no-simple.example.org" {
48483 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/123.example.org/pages/"
48484 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/123.example.org/pages/"
48485    server.name = "zzz.example.org"
48486  }
48487  
48488  $HTTP["host"] !~ "(no-simple\.example\.org)" {
48489    simple-vhost.document-root  = "pages"
48490 -  simple-vhost.server-root    = "@SRCDIR@/tmp/lighttpd/servers/"
48491 +  simple-vhost.server-root    = env.SRCDIR + "/tmp/lighttpd/servers/"
48492    simple-vhost.default-host   = "www.example.org"
48493  }
48494  
48495
48496 Property changes on: tests/lighttpd.conf
48497 ___________________________________________________________________
48498 Name: svn:eol-style
48499    + native
48500
48501 Index: tests/fastcgi-responder.conf
48502 ===================================================================
48503 --- tests/fastcgi-responder.conf        (.../tags/lighttpd-1.4.11)      (revision 1159)
48504 +++ tests/fastcgi-responder.conf        (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
48505 @@ -1,5 +1,5 @@
48506 -server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48507 -server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
48508 +server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48509 +server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
48510  
48511  #debug.log-request-header   = "enable"
48512  #debug.log-response-header  = "enable"
48513 @@ -15,7 +15,7 @@
48514  
48515  ## bind to localhost (default: all interfaces)
48516  server.bind                = "localhost"
48517 -server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
48518 +server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
48519  server.name                = "www.example.org"
48520  server.tag                 = "Apache 1.3.29"
48521  
48522 @@ -64,7 +64,7 @@
48523  ######################## MODULE CONFIG ############################
48524  
48525  
48526 -accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
48527 +accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
48528  
48529  mimetype.assign             = ( ".png"  => "image/png", 
48530                                  ".jpg"  => "image/jpeg",
48531 @@ -82,7 +82,7 @@
48532                                 ".c"    => "text/plain",
48533                                 ".conf" => "text/plain" )
48534  
48535 -compress.cache-dir          = "@SRCDIR@/tmp/lighttpd/cache/compress/"
48536 +compress.cache-dir          = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
48537  compress.filetype           = ("text/plain", "text/html")
48538  
48539  fastcgi.debug               = 0
48540 @@ -90,10 +90,11 @@
48541                                    "grisu" => ( 
48542                                     "host" => "127.0.0.1",
48543                                     "port" => 10000,
48544 -                                   "bin-path" => "@SRCDIR@/fcgi-responder",
48545 +                                   "bin-path" => env.SRCDIR + "/fcgi-responder",
48546                                     "check-local" => "disable",
48547                                     "max-procs" => 1,
48548 -                                   "min-procs" => 1
48549 +                                   "min-procs" => 1,
48550 +                                   "allow-x-send-file" => "enable",
48551                                   )
48552                                 )
48553                               )
48554 @@ -109,7 +110,7 @@
48555  ssl.pemfile                 = "server.pem"
48556  
48557  auth.backend                = "plain"
48558 -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
48559 +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
48560  auth.backend.plain.groupfile = "lighttpd.group"
48561  
48562  auth.backend.ldap.hostname  = "localhost"
48563 @@ -152,11 +153,11 @@
48564  status.config-url           = "/server-config"
48565  
48566  $HTTP["host"] == "vvv.example.org" {
48567 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48568 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48569  }
48570  
48571  $HTTP["host"] == "zzz.example.org" {
48572 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48573 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48574    server.name = "zzz.example.org"
48575  }
48576  
48577
48578 Property changes on: tests/fastcgi-responder.conf
48579 ___________________________________________________________________
48580 Name: svn:eol-style
48581    + native
48582
48583 Index: tests/fastcgi-auth.conf
48584 ===================================================================
48585 --- tests/fastcgi-auth.conf     (.../tags/lighttpd-1.4.11)      (revision 1159)
48586 +++ tests/fastcgi-auth.conf     (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
48587 @@ -1,5 +1,5 @@
48588 -server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48589 -server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd.pid"
48590 +server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48591 +server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd.pid"
48592  
48593  debug.log-request-header   = "enable"
48594  debug.log-response-header  = "enable"
48595 @@ -12,7 +12,7 @@
48596  
48597  ## bind to localhost (default: all interfaces)
48598  server.bind                = "localhost"
48599 -server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
48600 +server.errorlog            = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
48601  server.name                = "www.example.org"
48602  server.tag                 = "Apache 1.3.29"
48603  
48604 @@ -61,7 +61,7 @@
48605  ######################## MODULE CONFIG ############################
48606  
48607  
48608 -accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
48609 +accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
48610  
48611  mimetype.assign             = ( ".png"  => "image/png", 
48612                                  ".jpg"  => "image/jpeg",
48613 @@ -79,7 +79,7 @@
48614                                 ".c"    => "text/plain",
48615                                 ".conf" => "text/plain" )
48616  
48617 -compress.cache-dir          = "@SRCDIR@/tmp/lighttpd/cache/compress/"
48618 +compress.cache-dir          = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
48619  compress.filetype           = ("text/plain", "text/html")
48620  
48621  fastcgi.debug               = 0
48622 @@ -87,9 +87,9 @@
48623                                    "grisu" => ( 
48624                                     "host" => "127.0.0.1",
48625                                     "port" => 20000,
48626 -                                   "bin-path" => "@SRCDIR@/fcgi-auth",
48627 +                                   "bin-path" => env.SRCDIR + "/fcgi-auth",
48628                                      "mode" => "authorizer",
48629 -                                    "docroot" => "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/",
48630 +                                    "docroot" => env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/",
48631                                     
48632                                   )
48633                                 )
48634 @@ -106,7 +106,7 @@
48635  ssl.pemfile                 = "server.pem"
48636  
48637  auth.backend                = "plain"
48638 -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
48639 +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
48640  auth.backend.plain.groupfile = "lighttpd.group"
48641  
48642  auth.backend.ldap.hostname  = "localhost"
48643 @@ -149,11 +149,11 @@
48644  status.config-url           = "/server-config"
48645  
48646  $HTTP["host"] == "vvv.example.org" {
48647 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48648 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48649  }
48650  
48651  $HTTP["host"] == "zzz.example.org" {
48652 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48653 +  server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48654    server.name = "zzz.example.org"
48655  }
48656  
48657
48658 Property changes on: tests/fastcgi-auth.conf
48659 ___________________________________________________________________
48660 Name: svn:eol-style
48661    + native
48662
48663 Index: tests/proxy.conf
48664 ===================================================================
48665 --- tests/proxy.conf    (.../tags/lighttpd-1.4.11)      (revision 1159)
48666 +++ tests/proxy.conf    (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
48667 @@ -1,156 +1,26 @@
48668 -server.document-root         = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48669 -server.pid-file              = "@SRCDIR@/tmp/lighttpd/lighttpd-proxy.pid"
48670 +server.document-root         = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
48671 +server.pid-file              = env.SRCDIR + "/tmp/lighttpd/lighttpd-proxy.pid"
48672 +server.tag = "proxy"
48673  
48674 -## bind to port (default: 80)
48675 -server.port                 = 2050
48676 +include "default.conf"
48677  
48678 -## bind to localhost (default: all interfaces)
48679 -server.bind                = "localhost"
48680 -server.errorlog            = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.error.log"
48681 -server.name                = "www.example.org"
48682 -server.tag                 = "Proxy"
48683 -
48684 -server.dir-listing          = "enable"
48685 -
48686 -#server.event-handler        = "linux-sysepoll"
48687 -#server.event-handler        = "linux-rtsig"
48688 -
48689 -#server.modules.path         = ""
48690 -server.modules              = ( 
48691 -                               "mod_rewrite",
48692 -                               "mod_setenv",
48693 -                               "mod_access", 
48694 -                               "mod_auth",
48695 -#                              "mod_httptls",
48696 -                               "mod_status", 
48697 -                               "mod_expire",
48698 -                               "mod_simple_vhost",
48699 -                               "mod_redirect", 
48700 -#                              "mod_evhost",
48701 -#                              "mod_localizer",
48702 -                               "mod_fastcgi",
48703 -                               "mod_proxy",
48704 -                               "mod_cgi",
48705 -                               "mod_compress",
48706 -                               "mod_userdir",
48707 -                               "mod_accesslog" ) 
48708 -
48709 -server.indexfiles           = ( "index.php", "index.html", 
48710 -                                "index.htm", "default.htm" )
48711 -
48712 -
48713 -######################## MODULE CONFIG ############################
48714 -
48715 -
48716 -accesslog.filename          = "@SRCDIR@/tmp/lighttpd/logs/lighttpd.access.log"
48717 -
48718 -mimetype.assign             = ( ".png"  => "image/png", 
48719 -                                ".jpg"  => "image/jpeg",
48720 -                                ".jpeg" => "image/jpeg",
48721 -                                ".gif"  => "image/gif",
48722 -                                ".html" => "text/html",
48723 -                                ".htm"  => "text/html",
48724 -                                ".pdf"  => "application/pdf",
48725 -                                ".swf"  => "application/x-shockwave-flash",
48726 -                                ".spl"  => "application/futuresplash",
48727 -                                ".txt"  => "text/plain",
48728 -                                ".tar.gz" =>   "application/x-tgz",
48729 -                                ".tgz"  => "application/x-tgz",
48730 -                                ".gz"   => "application/x-gzip",
48731 -                               ".c"    => "text/plain",
48732 -                               ".conf" => "text/plain" )
48733 -
48734 -compress.cache-dir          = "@SRCDIR@/tmp/lighttpd/cache/compress/"
48735 -compress.filetype           = ("text/plain", "text/html")
48736 -
48737 -setenv.add-environment      = ( "TRAC_ENV" => "foo")
48738 -setenv.add-request-header   = ( "FOO" => "foo")
48739 -setenv.add-response-header  = ( "BAR" => "foo")
48740 -
48741 -proxy.debug = 1
48742 -proxy.server              = ( "" => ( 
48743 -                                  "grisu" => ( 
48744 -                                   "host" => "127.0.0.1",
48745 -                                   "port" => 2048,
48746 -                                 )
48747 -                               )
48748 -                             )
48749 +## 127.0.0.1 and 127.0.0.2 are the same host
48750 +proxy.server              = ( 
48751 +  "" => (( "host" => "127.0.0.1",
48752 +          "port" => 2050 ),
48753 +         ( "host" => "127.0.0.2",
48754 +           "port" => 2051 )
48755 +  ))
48756                 
48757 -
48758 -cgi.assign                  = ( ".pl"  => "/usr/bin/perl",
48759 -                                ".cgi" => "/usr/bin/perl",
48760 -                               ".py"  => "/usr/bin/python" )
48761 -                       
48762 -userdir.include-user = ( "jan" )
48763 -userdir.path = "/"
48764 -
48765 -ssl.engine                  = "disable"
48766 -ssl.pemfile                 = "server.pem"
48767 -
48768 -auth.backend                = "plain"
48769 -auth.backend.plain.userfile = "@SRCDIR@/tmp/lighttpd/lighttpd.user"
48770 -auth.backend.plain.groupfile = "lighttpd.group"
48771 -
48772 -auth.backend.ldap.hostname  = "localhost"
48773 -auth.backend.ldap.base-dn   = "dc=my-domain,dc=com"
48774 -auth.backend.ldap.filter    = "(uid=$)"
48775 -
48776 -auth.require                = ( "/server-status" => 
48777 -                                ( 
48778 -                                 "method"  => "digest",
48779 -                                 "realm"   => "download archiv",
48780 -#                                "require" => ("group=www", "user=jan", "host=192.168.2.10")
48781 -                                 "require" => "group=www|user=jan|host=192.168.2.10"
48782 -                               ),
48783 -                               "/auth.php" => 
48784 -                                ( 
48785 -                                 "method"  => "basic",
48786 -                                 "realm"   => "download archiv",
48787 -#                                "require" => ("group=www", "user=jan", "host=192.168.2.10")
48788 -                                 "require" => "user=jan"
48789 -                               ),
48790 -                               "/server-config" => 
48791 -                                ( 
48792 -                                 "method"  => "basic",
48793 -                                 "realm"   => "download archiv",
48794 -#                                "require" => ("group=www", "user=jan", "user=weigon", "host=192.168.2.10")
48795 -                                 "require" => "group=www|user=jan|host=192.168.2.10"
48796 -                               )
48797 -                              )
48798 -
48799 -url.access-deny             = ( "~", ".inc")
48800 -
48801 -url.redirect                = ( "^/redirect/$" => "http://localhost:2048/" )
48802 -
48803 -url.rewrite                = ( "^/rewrite/foo($|\?.+)" => "/indexfile/rewrite.php$1",
48804 -                               "^/rewrite/bar(?:$|\?(.+))" => "/indexfile/rewrite.php?bar&$1" )
48805 -
48806 -expire.url                  = ( "/expire/access" => "access 2 hours", 
48807 -                               "/expire/modification" => "access plus 1 seconds 2 minutes")
48808 -
48809 -#cache.cache-dir             = "/home/weigon/wwwroot/cache/"
48810 -
48811 -#### status module
48812 -status.status-url           = "/server-status"
48813 -status.config-url           = "/server-config"
48814 -
48815 -$HTTP["host"] == "vvv.example.org" {
48816 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48817 +$HTTP["url"] =~ "^/balance-rr/" {
48818 +  proxy.balance = "round-robin"
48819  }
48820  
48821 -$HTTP["host"] == "zzz.example.org" {
48822 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/www.example.org/pages/"
48823 -  server.name = "zzz.example.org"
48824 +$HTTP["url"] =~ "^/balance-hash/" {
48825 +  proxy.balance = "hash"
48826  }
48827  
48828 -$HTTP["host"] == "no-simple.example.org" {
48829 -  server.document-root = "@SRCDIR@/tmp/lighttpd/servers/123.example.org/pages/"
48830 -  server.name = "zzz.example.org"
48831 +$HTTP["url"] =~ "^/balance-fair/" {
48832 +  proxy.balance = "fair"
48833  }
48834  
48835 -$HTTP["host"] !~ "(no-simple\.example\.org)" {
48836 -  simple-vhost.document-root  = "pages"
48837 -  simple-vhost.server-root    = "@SRCDIR@/tmp/lighttpd/servers/"
48838 -  simple-vhost.default-host   = "www.example.org"
48839 -}
48840 -
48841
48842 Property changes on: tests/proxy.conf
48843 ___________________________________________________________________
48844 Name: svn:eol-style
48845    + native
48846
48847
48848 Property changes on: tests/prepare.sh
48849 ___________________________________________________________________
48850 Name: svn:eol-style
48851    + native
48852
48853 Index: tests/default.conf
48854 ===================================================================
48855 --- tests/default.conf  (.../tags/lighttpd-1.4.11)      (revision 0)
48856 +++ tests/default.conf  (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
48857 @@ -0,0 +1,111 @@
48858 +server.name                = "www.example.org"
48859 +
48860 +## bind to port (default: 80)
48861 +server.port                 = env.PORT
48862 +
48863 +
48864 +server.dir-listing          = "enable"
48865 +
48866 +#server.event-handler        = "linux-sysepoll"
48867 +#server.event-handler        = "linux-rtsig"
48868 +
48869 +server.modules              = ( 
48870 +                               "mod_rewrite",
48871 +                               "mod_setenv",
48872 +                               "mod_access", 
48873 +                               "mod_auth",
48874 +                               "mod_status", 
48875 +                               "mod_expire",
48876 +                               "mod_simple_vhost",
48877 +                               "mod_redirect", 
48878 +                               "mod_secdownload",
48879 +                               "mod_ssi",
48880 +                               "mod_fastcgi",
48881 +                               "mod_proxy",
48882 +                               "mod_cgi",
48883 +                               "mod_compress",
48884 +                               "mod_userdir",
48885 +                               "mod_accesslog" ) 
48886 +
48887 +server.indexfiles           = ( "index.php", "index.html", 
48888 +                                "index.htm", "default.htm" )
48889 +
48890 +ssi.extension = ( ".shtml" )
48891 +
48892 +######################## MODULE CONFIG ############################
48893 +
48894 +
48895 +accesslog.filename          = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.access.log"
48896 +server.errorlog             = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.error.log"
48897 +
48898 +mimetype.assign             = ( ".png"  => "image/png", 
48899 +                                ".jpg"  => "image/jpeg",
48900 +                                ".jpeg" => "image/jpeg",
48901 +                                ".gif"  => "image/gif",
48902 +                                ".html" => "text/html",
48903 +                                ".htm"  => "text/html",
48904 +                                ".pdf"  => "application/pdf",
48905 +                                ".swf"  => "application/x-shockwave-flash",
48906 +                                ".spl"  => "application/futuresplash",
48907 +                                ".txt"  => "text/plain",
48908 +                                ".tar.gz" =>   "application/x-tgz",
48909 +                                ".tgz"  => "application/x-tgz",
48910 +                                ".gz"   => "application/x-gzip",
48911 +                               ".c"    => "text/plain",
48912 +                               ".conf" => "text/plain" )
48913 +
48914 +compress.cache-dir          = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
48915 +compress.filetype           = ("text/plain", "text/html")
48916 +
48917 +setenv.add-environment      = ( "TRAC_ENV" => "tracenv", "SETENV" => "setenv")
48918 +
48919 +cgi.assign                  = ( ".pl"  => "/usr/bin/perl",
48920 +                                ".cgi" => "/usr/bin/perl",
48921 +                               ".py"  => "/usr/bin/python" )
48922 +                       
48923 +userdir.include-user = ( "jan" )
48924 +userdir.path = "/"
48925 +
48926 +ssl.engine                  = "disable"
48927 +ssl.pemfile                 = "server.pem"
48928 +
48929 +auth.backend                = "plain"
48930 +auth.backend.plain.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.user"
48931 +auth.backend.htpasswd.userfile = env.SRCDIR + "/tmp/lighttpd/lighttpd.htpasswd"
48932 +auth.backend.plain.groupfile = "lighttpd.group"
48933 +
48934 +auth.backend.ldap.hostname  = "localhost"
48935 +auth.backend.ldap.base-dn   = "dc=my-domain,dc=com"
48936 +auth.backend.ldap.filter    = "(uid=$)"
48937 +
48938 +auth.require                = ( "/server-status" => 
48939 +                                ( 
48940 +                                 "method"  => "digest",
48941 +                                 "realm"   => "download archiv",
48942 +                                 "require" => "valid-user"
48943 +                               ),
48944 +                               "/auth.php" => 
48945 +                                ( 
48946 +                                 "method"  => "basic",
48947 +                                 "realm"   => "download archiv",
48948 +                                 "require" => "user=jan"
48949 +                               ),
48950 +                               "/server-config" => 
48951 +                                ( 
48952 +                                 "method"  => "basic",
48953 +                                 "realm"   => "download archiv",
48954 +                                 "require" => "valid-user"
48955 +                               )
48956 +                              )
48957 +
48958 +url.access-deny             = ( "~", ".inc")
48959 +
48960 +url.redirect                = ( "^/redirect/$" => "http://localhost:2048/" )
48961 +
48962 +url.rewrite                = ( "^/rewrite/foo($|\?.+)" => "/indexfile/rewrite.php$1",
48963 +                               "^/rewrite/bar(?:$|\?(.+))" => "/indexfile/rewrite.php?bar&$1" )
48964 +
48965 +#### status module
48966 +status.status-url           = "/server-status"
48967 +status.config-url           = "/server-config"
48968 +
48969
48970 Property changes on: tests/default.conf
48971 ___________________________________________________________________
48972 Name: svn:eol-style
48973    + native
48974
48975
48976 Property changes on: tests/docroot/www/get-header.pl
48977 ___________________________________________________________________
48978 Name: svn:eol-style
48979    + native
48980
48981
48982 Property changes on: tests/docroot/www/nph-status.pl
48983 ___________________________________________________________________
48984 Name: svn:eol-style
48985    + native
48986
48987
48988 Property changes on: tests/docroot/www/cgi-pathinfo.pl
48989 ___________________________________________________________________
48990 Name: svn:eol-style
48991    + native
48992
48993
48994 Property changes on: tests/docroot/www/ssi.shtml
48995 ___________________________________________________________________
48996 Name: svn:eol-style
48997    + native
48998
48999
49000 Property changes on: tests/docroot/www/index.txt
49001 ___________________________________________________________________
49002 Name: svn:eol-style
49003    + native
49004
49005
49006 Property changes on: tests/docroot/www/exec-date.shtml
49007 ___________________________________________________________________
49008 Name: svn:eol-style
49009    + native
49010
49011
49012 Property changes on: tests/docroot/www/redirect.php
49013 ___________________________________________________________________
49014 Name: svn:eol-style
49015    + native
49016
49017
49018 Property changes on: tests/docroot/www/get-post-len.pl
49019 ___________________________________________________________________
49020 Name: svn:eol-style
49021    + native
49022
49023
49024 Property changes on: tests/docroot/www/cgi.php
49025 ___________________________________________________________________
49026 Name: svn:eol-style
49027    + native
49028
49029
49030 Property changes on: tests/docroot/www/phpinfo.php
49031 ___________________________________________________________________
49032 Name: svn:eol-style
49033    + native
49034
49035
49036 Property changes on: tests/docroot/www/get-env.php
49037 ___________________________________________________________________
49038 Name: svn:eol-style
49039    + native
49040
49041
49042 Property changes on: tests/docroot/www/expire/access.txt
49043 ___________________________________________________________________
49044 Name: svn:eol-style
49045    + native
49046
49047
49048 Property changes on: tests/docroot/www/expire/modification.txt
49049 ___________________________________________________________________
49050 Name: svn:eol-style
49051    + native
49052
49053
49054 Property changes on: tests/docroot/www/expire/Makefile.am
49055 ___________________________________________________________________
49056 Name: svn:eol-style
49057    + native
49058
49059
49060 Property changes on: tests/docroot/www/get-server-env.php
49061 ___________________________________________________________________
49062 Name: svn:eol-style
49063    + native
49064
49065
49066 Property changes on: tests/docroot/www/prefix.fcgi
49067 ___________________________________________________________________
49068 Name: svn:eol-style
49069    + native
49070
49071
49072 Property changes on: tests/docroot/www/go/cgi.php
49073 ___________________________________________________________________
49074 Name: svn:eol-style
49075    + native
49076
49077
49078 Property changes on: tests/docroot/www/go/Makefile.am
49079 ___________________________________________________________________
49080 Name: svn:eol-style
49081    + native
49082
49083
49084 Property changes on: tests/docroot/www/indexfile/rewrite.php
49085 ___________________________________________________________________
49086 Name: svn:eol-style
49087    + native
49088
49089
49090 Property changes on: tests/docroot/www/indexfile/Makefile.am
49091 ___________________________________________________________________
49092 Name: svn:eol-style
49093    + native
49094
49095
49096 Property changes on: tests/docroot/www/indexfile/return-404.php
49097 ___________________________________________________________________
49098 Name: svn:eol-style
49099    + native
49100
49101
49102 Property changes on: tests/docroot/www/indexfile/index.php
49103 ___________________________________________________________________
49104 Name: svn:eol-style
49105    + native
49106
49107
49108 Property changes on: tests/docroot/www/Makefile.am
49109 ___________________________________________________________________
49110 Name: svn:eol-style
49111    + native
49112
49113
49114 Property changes on: tests/docroot/www/index.html
49115 ___________________________________________________________________
49116 Name: svn:eol-style
49117    + native
49118
49119
49120 Property changes on: tests/docroot/www/cgi.pl
49121 ___________________________________________________________________
49122 Name: svn:eol-style
49123    + native
49124
49125
49126 Property changes on: tests/docroot/123/12345.html
49127 ___________________________________________________________________
49128 Name: svn:eol-style
49129    + native
49130
49131
49132 Property changes on: tests/docroot/123/dummyfile.bla
49133 ___________________________________________________________________
49134 Name: svn:eol-style
49135    + native
49136
49137
49138 Property changes on: tests/docroot/123/Makefile.am
49139 ___________________________________________________________________
49140 Name: svn:eol-style
49141    + native
49142
49143
49144 Property changes on: tests/docroot/123/phpinfo.php
49145 ___________________________________________________________________
49146 Name: svn:eol-style
49147    + native
49148
49149
49150 Property changes on: tests/docroot/123/12345.txt
49151 ___________________________________________________________________
49152 Name: svn:eol-style
49153    + native
49154
49155
49156 Property changes on: tests/docroot/Makefile.am
49157 ___________________________________________________________________
49158 Name: svn:eol-style
49159    + native
49160
49161 Index: tests/Makefile.am
49162 ===================================================================
49163 --- tests/Makefile.am   (.../tags/lighttpd-1.4.11)      (revision 1159)
49164 +++ tests/Makefile.am   (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
49165 @@ -39,10 +39,15 @@
49166        mod-redirect.t \
49167        mod-userdir.t \
49168        mod-rewrite.t \
49169 +      mod-proxy.t \
49170        request.t \
49171        mod-ssi.t \
49172        LightyTest.pm \
49173 -      mod-setenv.t 
49174 +      mod-setenv.t \
49175 +      lowercase.t \
49176 +      lowercase.conf \
49177 +      proxy.conf \
49178 +      cachable.t
49179  
49180  
49181  TESTS_ENVIRONMENT=$(srcdir)/wrapper.sh $(srcdir) $(top_builddir) 
49182
49183 Property changes on: tests/Makefile.am
49184 ___________________________________________________________________
49185 Name: svn:eol-style
49186    + native
49187
49188
49189 Property changes on: tests/mod-compress.t
49190 ___________________________________________________________________
49191 Name: svn:eol-style
49192    + native
49193
49194 Index: tests/LightyTest.pm
49195 ===================================================================
49196 --- tests/LightyTest.pm (.../tags/lighttpd-1.4.11)      (revision 1159)
49197 +++ tests/LightyTest.pm (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
49198 @@ -87,14 +87,14 @@
49199         # pre-process configfile if necessary
49200         #
49201  
49202 -       unlink($self->{TESTDIR}."/tmp/cfg.file");
49203 -       system("cat ".$self->{SRCDIR}."/".$self->{CONFIGFILE}.' | perl -pe "s#\@SRCDIR\@#'.$self->{BASEDIR}.'/tests/#" > '.$self->{TESTDIR}.'/tmp/cfg.file');
49204 +       $ENV{'SRCDIR'} = $self->{BASEDIR}.'/tests';
49205 +       $ENV{'PORT'} = $self->{PORT};
49206  
49207         unlink($self->{LIGHTTPD_PIDFILE});
49208         if (1) {
49209 -               system($self->{LIGHTTPD_PATH}." -f ".$self->{TESTDIR}."/tmp/cfg.file -m ".$self->{MODULES_PATH});
49210 +               system($self->{LIGHTTPD_PATH}." -f ".$self->{SRCDIR}."/".$self->{CONFIGFILE}." -m ".$self->{MODULES_PATH});
49211         } else {
49212 -               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}." &");
49213 +               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}." &");
49214         }
49215  
49216         select(undef, undef, undef, 0.1);
49217 @@ -184,7 +184,7 @@
49218                                         (my $h = $1) =~ tr/[A-Z]/[a-z]/;
49219  
49220                                         if (defined $resp_hdr{$h}) {
49221 -                                               diag(sprintf("header %s is duplicated: %s and %s\n",
49222 +                                               diag(sprintf("header '%s' is duplicated: '%s' and '%s'\n",
49223                                                              $h, $resp_hdr{$h}, $2));
49224                                         } else {
49225                                                 $resp_hdr{$h} = $2;
49226 @@ -196,6 +196,9 @@
49227                         }
49228                 }
49229  
49230 +               $t->{etag} = $resp_hdr{'etag'};
49231 +               $t->{date} = $resp_hdr{'date'};
49232 +
49233                 # check length
49234                 if (defined $resp_hdr{"content-length"}) {
49235                         $resp_body = substr($lines, 0, $resp_hdr{"content-length"});
49236
49237 Property changes on: tests/LightyTest.pm
49238 ___________________________________________________________________
49239 Name: svn:eol-style
49240    + native
49241
49242
49243 Property changes on: tests/mod-ssi.t
49244 ___________________________________________________________________
49245 Name: svn:eol-style
49246    + native
49247
49248
49249 Property changes on: tests/core-condition.t
49250 ___________________________________________________________________
49251 Name: svn:eol-style
49252    + native
49253
49254
49255 Property changes on: tests/run-tests.pl
49256 ___________________________________________________________________
49257 Name: svn:eol-style
49258    + native
49259
49260
49261 Property changes on: tests
49262 ___________________________________________________________________
49263 Name: svn:ignore
49264    - Makefile.in
49265 Makefile
49266 .deps
49267 .libs
49268 fcgi-auth
49269 fcgi-responder
49270
49271    + Makefile.in
49272 Makefile
49273 .deps
49274 .libs
49275 fcgi-auth
49276 fcgi-responder
49277 *.swp
49278 tmp
49279
49280
49281
49282 Property changes on: doc/redirect.txt
49283 ___________________________________________________________________
49284 Name: svn:eol-style
49285    + native
49286
49287 Index: doc/performance.txt
49288 ===================================================================
49289 --- doc/performance.txt (.../tags/lighttpd-1.4.11)      (revision 1159)
49290 +++ doc/performance.txt (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
49291 @@ -183,6 +183,8 @@
49292  
49293    server.stat-cache-engine = "fam"   # either fam, simple or disabled
49294  
49295 +See http://oss.sgi.com/projects/fam/faq.html for information about FAM.
49296 +See http://www.gnome.org/~veillard/gamin/overview.html for information about gamin.
49297  
49298  Platform-Specific Notes
49299  =======================
49300
49301 Property changes on: doc/performance.txt
49302 ___________________________________________________________________
49303 Name: svn:eol-style
49304    + native
49305
49306
49307 Property changes on: doc/ssl.txt
49308 ___________________________________________________________________
49309 Name: svn:eol-style
49310    + native
49311
49312 Index: doc/secdownload.txt
49313 ===================================================================
49314 --- doc/secdownload.txt (.../tags/lighttpd-1.4.11)      (revision 1159)
49315 +++ doc/secdownload.txt (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
49316 @@ -118,7 +118,7 @@
49317    $secret = "verysecret";
49318    $uri_prefix = "/dl/";
49319    
49320 -  # filename
49321 +  # filename, make sure it's started with a "/" or you'll get 404 in the browser
49322    $f = "/secret-file.txt";
49323    
49324    # current timestamp
49325
49326 Property changes on: doc/secdownload.txt
49327 ___________________________________________________________________
49328 Name: svn:eol-style
49329    + native
49330
49331
49332 Property changes on: doc/accesslog.txt
49333 ___________________________________________________________________
49334 Name: svn:eol-style
49335    + native
49336
49337
49338 Property changes on: doc/setenv.txt
49339 ___________________________________________________________________
49340 Name: svn:eol-style
49341    + native
49342
49343
49344 Property changes on: doc/sysconfig.lighttpd
49345 ___________________________________________________________________
49346 Name: svn:eol-style
49347    + native
49348
49349
49350 Property changes on: doc/traffic-shaping.txt
49351 ___________________________________________________________________
49352 Name: svn:eol-style
49353    + native
49354
49355
49356 Property changes on: doc/security.txt
49357 ___________________________________________________________________
49358 Name: svn:eol-style
49359    + native
49360
49361
49362 Property changes on: doc/trigger_b4_dl.txt
49363 ___________________________________________________________________
49364 Name: svn:eol-style
49365    + native
49366
49367
49368 Property changes on: doc/spawn-php.sh
49369 ___________________________________________________________________
49370 Name: svn:eol-style
49371    + native
49372
49373
49374 Property changes on: doc/webdav.txt
49375 ___________________________________________________________________
49376 Name: svn:eol-style
49377    + native
49378
49379
49380 Property changes on: doc/rc.lighttpd.redhat
49381 ___________________________________________________________________
49382 Name: svn:eol-style
49383    + native
49384
49385
49386 Property changes on: doc/userdir.txt
49387 ___________________________________________________________________
49388 Name: svn:eol-style
49389    + native
49390
49391
49392 Property changes on: doc/features.txt
49393 ___________________________________________________________________
49394 Name: svn:eol-style
49395    + native
49396
49397
49398 Property changes on: doc/rrdtool-graph.sh
49399 ___________________________________________________________________
49400 Name: svn:eol-style
49401    + native
49402
49403
49404 Property changes on: doc/proxy.txt
49405 ___________________________________________________________________
49406 Name: svn:eol-style
49407    + native
49408
49409
49410 Property changes on: doc/status.txt
49411 ___________________________________________________________________
49412 Name: svn:eol-style
49413    + native
49414
49415
49416 Property changes on: doc/mysqlvhost.txt
49417 ___________________________________________________________________
49418 Name: svn:eol-style
49419    + native
49420
49421 Index: doc/compress.txt
49422 ===================================================================
49423 --- doc/compress.txt    (.../tags/lighttpd-1.4.11)      (revision 1159)
49424 +++ doc/compress.txt    (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
49425 @@ -22,13 +22,39 @@
49426  ===========
49427  
49428  Output compression reduces the network load and can improve the overall
49429 -throughput of the webserver. 
49430 +throughput of the webserver. All major http-clients support compression by
49431 +announcing it in the Accept-Encoding header. This is used to negotiate the 
49432 +most suitable compression method. We support deflate, gzip and bzip2.
49433  
49434 -Only static content is supported up to now.
49435 +deflate (RFC1950, RFC1951) and gzip (RFC1952) depend on zlib while bzip2 
49436 +depends on libbzip2. bzip2 is only supported by lynx and some other console
49437 +text-browsers.
49438  
49439 -The server negotiates automaticly which compression method is used.
49440 -Supported are gzip, deflate, bzip.
49441 +Currently we limit to compression support to static files.
49442  
49443 +Caching
49444 +-------
49445 +
49446 +mod_compress can stored compressed files on disk to optimized the compression
49447 +on a second request away. As soon as compress.cache-dir is set the files are
49448 +compressed. 
49449 +
49450 +The names of the cache files are made of the filename, the compression method
49451 +and the etag associated to the file.
49452 +
49453 +Cleaning the cache is left to the user. A cron job deleting files older than
49454 +10 days should do fine.
49455 +
49456 +Limitations
49457 +-----------
49458 +
49459 +The module limits the compression of files to files larger than 128 Byte and
49460 +smaller than 128 MByte.
49461 +
49462 +The lower limit is set as small files tend to become larger by compressing due
49463 +to the compression headers, the upper limit is set to work sensable with
49464 +memory and cpu-time.
49465 +
49466  Options
49467  =======
49468  
49469 @@ -47,15 +73,28 @@
49470    Default: not set, compress the file for every request
49471  
49472  compress.filetype
49473 -  mimetypes where might get compressed
49474 +  mimetypes which might get compressed
49475    
49476    e.g.: ::
49477    
49478      compress.filetype           = ("text/plain", "text/html")
49479  
49480 +  Keep in mind that compressed JavaScript and CSS files are broken in some
49481 +  browsers.
49482 +
49483    Default: not set
49484  
49485 +compress.max-file-size 
49486 +  maximum size of the original file to be compressed kBytes.
49487  
49488 +  This is meant to protect the server against DoSing as compressing large
49489 +  (let's say 1Gbyte) takes a lot of time and would delay the whole operation
49490 +  of the server.
49491 +
49492 +  There is a hard upper limit of 128Mbyte.
49493 +
49494 +  Default: unlimited (== hard-limit of 128MByte)
49495 +  
49496  Compressing Dynamic Content
49497  ===========================
49498  
49499
49500 Property changes on: doc/compress.txt
49501 ___________________________________________________________________
49502 Name: svn:eol-style
49503    + native
49504
49505
49506 Property changes on: doc/fastcgi-state.txt
49507 ___________________________________________________________________
49508 Name: svn:eol-style
49509    + native
49510
49511
49512 Property changes on: doc/.cvsignore
49513 ___________________________________________________________________
49514 Name: svn:eol-style
49515    + native
49516
49517
49518 Property changes on: doc/lighttpd.1
49519 ___________________________________________________________________
49520 Name: svn:eol-style
49521    + native
49522
49523
49524 Property changes on: doc/access.txt
49525 ___________________________________________________________________
49526 Name: svn:eol-style
49527    + native
49528
49529
49530 Property changes on: doc/cgi.txt
49531 ___________________________________________________________________
49532 Name: svn:eol-style
49533    + native
49534
49535
49536 Property changes on: doc/rc.lighttpd
49537 ___________________________________________________________________
49538 Name: svn:eol-style
49539    + native
49540
49541
49542 Property changes on: doc/fastcgi-state.dot
49543 ___________________________________________________________________
49544 Name: svn:eol-style
49545    + native
49546
49547 Index: doc/configuration.txt
49548 ===================================================================
49549 --- doc/configuration.txt       (.../tags/lighttpd-1.4.11)      (revision 1159)
49550 +++ doc/configuration.txt       (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
49551 @@ -511,3 +511,10 @@
49552  
49553  debug.log-request-handling
49554    default: disabled 
49555 +
49556 +debug.log-condition-handling
49557 +  default: disabled 
49558 +
49559 +debug.log-condition-cache-handling
49560 +  for developers only
49561 +  default: disabled 
49562
49563 Property changes on: doc/configuration.txt
49564 ___________________________________________________________________
49565 Name: svn:eol-style
49566    + native
49567
49568
49569 Property changes on: doc/oldstyle.css
49570 ___________________________________________________________________
49571 Name: svn:eol-style
49572    + native
49573
49574
49575 Property changes on: doc/dirlisting.txt
49576 ___________________________________________________________________
49577 Name: svn:eol-style
49578    + native
49579
49580
49581 Property changes on: doc/evhost.txt
49582 ___________________________________________________________________
49583 Name: svn:eol-style
49584    + native
49585
49586
49587 Property changes on: doc/cml.txt
49588 ___________________________________________________________________
49589 Name: svn:eol-style
49590    + native
49591
49592
49593 Property changes on: doc/lighttpd.user
49594 ___________________________________________________________________
49595 Name: svn:eol-style
49596    + native
49597
49598
49599 Property changes on: doc/authentication.txt
49600 ___________________________________________________________________
49601 Name: svn:eol-style
49602    + native
49603
49604
49605 Property changes on: doc/spawn-fcgi.1
49606 ___________________________________________________________________
49607 Name: svn:eol-style
49608    + native
49609
49610 Index: doc/fastcgi.txt
49611 ===================================================================
49612 --- doc/fastcgi.txt     (.../tags/lighttpd-1.4.11)      (revision 1159)
49613 +++ doc/fastcgi.txt     (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
49614 @@ -144,8 +144,8 @@
49615                  PHP can extract PATH_INFO from it (default: disabled)
49616    :"disable-time": time to wait before a disabled backend is checked
49617                  again
49618 -  :"allow-x-send-file": controls if X-LIGHTTPD-send-file headers
49619 -                are allowed 
49620 +  :"allow-x-send-file": controls if X-LIGHTTPD-send-file and X-Sendfile
49621 +                headers are allowed 
49622  
49623    If bin-path is set:
49624  
49625
49626 Property changes on: doc/fastcgi.txt
49627 ___________________________________________________________________
49628 Name: svn:eol-style
49629    + native
49630
49631
49632 Property changes on: doc/state.txt
49633 ___________________________________________________________________
49634 Name: svn:eol-style
49635    + native
49636
49637
49638 Property changes on: doc/rewrite.txt
49639 ___________________________________________________________________
49640 Name: svn:eol-style
49641    + native
49642
49643
49644 Property changes on: doc/plugins.txt
49645 ___________________________________________________________________
49646 Name: svn:eol-style
49647    + native
49648
49649
49650 Property changes on: doc/newstyle.css
49651 ___________________________________________________________________
49652 Name: svn:eol-style
49653    + native
49654
49655
49656 Property changes on: doc/skeleton.txt
49657 ___________________________________________________________________
49658 Name: svn:eol-style
49659    + native
49660
49661
49662 Property changes on: doc/rrdtool.txt
49663 ___________________________________________________________________
49664 Name: svn:eol-style
49665    + native
49666
49667 Index: doc/lighttpd.conf
49668 ===================================================================
49669 --- doc/lighttpd.conf   (.../tags/lighttpd-1.4.11)      (revision 1159)
49670 +++ doc/lighttpd.conf   (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
49671 @@ -172,10 +172,11 @@
49672  #dir-listing.activate       = "enable"
49673  
49674  ## enable debugging
49675 -#debug.log-request-header   = "enable"
49676 -#debug.log-response-header  = "enable"
49677 -#debug.log-request-handling = "enable"
49678 -#debug.log-file-not-found   = "enable"
49679 +#debug.log-request-header     = "enable"
49680 +#debug.log-response-header    = "enable"
49681 +#debug.log-request-handling   = "enable"
49682 +#debug.log-file-not-found     = "enable"
49683 +#debug.log-condition-handling = "enable"
49684  
49685  ### only root can use these options
49686  #
49687
49688 Property changes on: doc/lighttpd.conf
49689 ___________________________________________________________________
49690 Name: svn:eol-style
49691    + native
49692
49693
49694 Property changes on: doc/scgi.txt
49695 ___________________________________________________________________
49696 Name: svn:eol-style
49697    + native
49698
49699
49700 Property changes on: doc/state.dot
49701 ___________________________________________________________________
49702 Name: svn:eol-style
49703    + native
49704
49705
49706 Property changes on: doc/alias.txt
49707 ___________________________________________________________________
49708 Name: svn:eol-style
49709    + native
49710
49711
49712 Property changes on: doc/simple-vhost.txt
49713 ___________________________________________________________________
49714 Name: svn:eol-style
49715    + native
49716
49717
49718 Property changes on: doc/Makefile.am
49719 ___________________________________________________________________
49720 Name: svn:eol-style
49721    + native
49722
49723
49724 Property changes on: doc/expire.txt
49725 ___________________________________________________________________
49726 Name: svn:eol-style
49727    + native
49728
49729
49730 Property changes on: doc/ssi.txt
49731 ___________________________________________________________________
49732 Name: svn:eol-style
49733    + native
49734
49735
49736 Property changes on: INSTALL
49737 ___________________________________________________________________
49738 Name: svn:eol-style
49739    + native
49740
49741 Index: SConstruct
49742 ===================================================================
49743 --- SConstruct  (.../tags/lighttpd-1.4.11)      (revision 1159)
49744 +++ SConstruct  (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
49745 @@ -82,6 +82,8 @@
49746         PackageOption('with_xml', 'enable xml support', 'no'),
49747         PackageOption('with_pcre', 'enable pcre support', 'yes'),
49748         PathOption('CC', 'path to the c-compiler', None),
49749 +    PathOption('PSDK_HOME', 'path to the platform SDK', None),
49750 +    PathOption('VC_TOOLKIT_HOME', 'path to the Visual C++ Toolkit', None),
49751         BoolOption('build_dynamic', 'enable dynamic build', 'yes'),
49752         BoolOption('build_static', 'enable static build', 'no'),
49753         BoolOption('build_fullstatic', 'enable fullstatic build', 'no'),
49754 @@ -92,25 +94,46 @@
49755         BoolOption('with_gzip', 'enable gzip compression', 'no'),
49756         BoolOption('with_bzip2', 'enable bzip2 compression', 'no'),
49757         BoolOption('with_lua', 'enable lua support for mod_cml', 'no'),
49758 +       BoolOption('with_uuid', 'enable LOCK support (requires uuid) for mod_webdav', 'no'),
49759         BoolOption('with_ldap', 'enable ldap auth support', 'no'))
49760  
49761  env = Environment(
49762 -       env = os.environ,
49763 -       options = opts,
49764 -       CPPPATH = Split('#build')
49765 +       options = opts
49766  )
49767  
49768  env.Help(opts.GenerateHelpText(env))
49769 +cpppath = [ '#build/' ]
49770 +libpath = [ '/lib/', '/usr/lib/', '/usr/local/lib/' ]
49771 +path = [ '/bin/', '/usr/bin/' ]
49772  
49773  if env.subst('${CC}') is not '':
49774         env['CC'] = env.subst('${CC}')
49775  
49776 +if env.subst('${VC_TOOLKIT_HOME}') is not '': 
49777 +       cpppath += [ '${VC_TOOLKIT_HOME}/include' ]
49778 +       libpath += [ '${VC_TOOLKIT_HOME}/lib' ]
49779 +       path += [ env.subst('${VC_TOOLKIT_HOME}/bin') ]
49780 +
49781 +if env.subst('${PSDK_HOME}') is not '': 
49782 +       cpppath += [ '${PSDK_HOME}/include' ]
49783 +       libpath += [ '${PSDK_HOME}/lib' ]
49784 +       path += [ env.subst('${PSDK_HOME}/bin') ]
49785 +
49786 +
49787 +## build new environment with a clean PATH
49788 +
49789 +env = Environment(options = opts, ENV = { "PATH" : path})
49790 +
49791 +env.Append(CPPPATH = cpppath)
49792 +env.Append(LIBPATH = libpath)
49793 +
49794  env['package'] = package
49795  env['version'] = version
49796  if env['CC'] == 'gcc':
49797         ## we need x-open 6 and bsd 4.3 features
49798         env.Append(CCFLAGS = Split('-Wall -O2 -g -W -pedantic -Wunused -Wshadow -std=gnu99'))
49799 -
49800 +else:
49801 +    env.Append(CCFLAGS = Split('/Zi /W3'))
49802  # cache configure checks
49803  if 1:
49804         autoconf = Configure(env, custom_tests = {'CheckStructMember': checkStructMember })
49805 @@ -158,7 +181,7 @@
49806         checkFuncs(autoconf, Split('fork stat lstat strftime dup2 getcwd inet_ntoa inet_ntop memset mmap munmap strchr \
49807                         strdup strerror strstr strtol sendfile  getopt socket \
49808                         gethostbyname poll sigtimedwait epoll_ctl getrlimit chroot \
49809 -                       getuid select signal pathconf madvise prctl\
49810 +                       getuid select signal pathconf madvise prctl inet_aton \
49811                         writev sigaction sendfile64 send_file kqueue port_create localtime_r posix_fadvise'))
49812  
49813         checkTypes(autoconf, Split('pid_t size_t off_t'))
49814 @@ -206,6 +229,10 @@
49815                 if autoconf.CheckLibWithHeader('lua', 'lua.h', 'C'):
49816                         autoconf.env.Append(CPPFLAGS = [ '-DHAVE_LUA_H', '-DHAVE_LIBLUA' ], LIBLUA = 'lua', LIBLUALIB = 'lualib')
49817         
49818 +       if env['with_uuid']:
49819 +               if autoconf.CheckLibWithHeader('uuid', 'uuid/uuid.h', 'C'):
49820 +                       autoconf.env.Append(CPPFLAGS = [ '-DHAVE_UUID_H' ], LIBUUID = 'uuid')
49821 +
49822         ol = env['LIBS']
49823         if autoconf.CheckLibWithHeader('fcgi', 'fastcgi.h', 'C'):
49824                 autoconf.env.Append(LIBFCGI = 'fcgi')
49825 @@ -252,6 +279,9 @@
49826         env.Append(COMMON_LIB = 'bin')
49827  elif re.compile("darwin|aix").search(env['PLATFORM']):
49828         env.Append(COMMON_LIB = 'lib')
49829 +elif re.compile("win32").search(env['PLATFORM']):
49830 +    env['LIBS'] += [ 'wsock32' ]
49831 +    env.Append(COMMON_LIB = False)
49832  else:
49833         env.Append(COMMON_LIB = False)
49834  
49835
49836 Property changes on: SConstruct
49837 ___________________________________________________________________
49838 Name: svn:eol-style
49839    + native
49840
49841
49842 Property changes on: COPYING
49843 ___________________________________________________________________
49844 Name: svn:eol-style
49845    + native
49846
49847
49848 Property changes on: Makefile.am
49849 ___________________________________________________________________
49850 Name: svn:eol-style
49851    + native
49852
49853
49854 Property changes on: config.py-sample
49855 ___________________________________________________________________
49856 Name: svn:eol-style
49857    + native
49858
49859
49860 Property changes on: autogen.sh
49861 ___________________________________________________________________
49862 Name: svn:eol-style
49863    + native
49864
49865 Index: INSTALL.svn
49866 ===================================================================
49867 --- INSTALL.svn (.../tags/lighttpd-1.4.11)      (revision 0)
49868 +++ INSTALL.svn (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
49869 @@ -0,0 +1,88 @@
49870 +
49871 +============
49872 +Installation from svn repo
49873 +============
49874 +
49875 +:author: mOo
49876 +:Date: $Date$
49877 +:Revision: $Revision$
49878 +
49879 +Prerequirement
49880 +------------
49881 +subversion (required, for svn co, svn up)
49882 +perl (optional, for check)
49883 +php (optional, for check)
49884 +
49885 +Choose one of the build systems:
49886 +1. build with autotools
49887 +autotools (required for autogen.sh)
49888 +
49889 +2. build with scons:
49890 +an text editor (for config.py)
49891 +scons v0.96.91.D001 or newer (required for scons build)
49892 +
49893 +Check out the source
49894 +------------
49895 +Review which source you want to checkout at:
49896 +http://trac.lighttpd.net/trac/browser
49897 +http://trac.lighttpd.net/trac/browser/tags
49898 +
49899 +note the current lastest version is lighttpd-merge-1.4.x not trunk:
49900 +http://trac.lighttpd.net/trac/browser/branches/lighttpd-merge-1.4.x
49901 +
49902 +and check it out by ::
49903 +
49904 +  svn co svn://svn.lighttpd.net/lighttpd/branches/lighttpd-merge-1.4.x
49905 +
49906 +
49907 +Build, Test and Install
49908 +------------
49909 +
49910 +with autoconf
49911 +------------
49912 +
49913 +  $ cd lighttpd-1.x.x
49914 +  $ ./autogen.sh
49915 +if you have problem with autogen.sh, check aclocal autoconf automake version
49916 +
49917 +check configure options
49918 +  $ ./configure --help
49919 +  $ ./configure --prefix=/usr/local/lighttpd/ --enable-...
49920 +  $ make clean
49921 +  $ make check
49922 +  $ src/lighttpd -Df your_test.conf
49923 +  (Ctrl+C once or twice to terminate lighttpd)
49924 +  $ su -
49925 +  # make install
49926 +  # exit
49927 +
49928 +with scons
49929 +------------
49930 +copy and modify config.py for your own needs with your favorite editor:
49931 +  $ cp config.py-sample config.py
49932 +  $ $EDITOR config.py
49933 +
49934 +make sure your scons version is up to date, v0.96.91.D001 works. old version is known to have problem to build lighttpd.
49935 +  $ scons --version
49936 +  $ scons
49937 +  $ scons check
49938 +  $ src/lighttpd -Df your_test.conf
49939 +  (Ctrl+C once or twice to terminate lighttpd)
49940 +
49941 +  $ su -
49942 +  # scons install
49943 +as scons make some file owned by root now, you have to do:
49944 +  # chown yourusername:yourgroup -R .
49945 +  # exit
49946 +
49947 +
49948 +take look at the configfile in ./doc/lighttpd.conf,
49949 +make your own copy of that file before modify it for your needs.
49950 +
49951 +Keep up to date with lastest svn repo
49952 +------------
49953 +simply do:
49954 +  $ svn up
49955 +and follow the instructions in "Build and Install".
49956 +
49957 +Do not make a non-released version on production server, you have been warned.
49958
49959 Property changes on: INSTALL.svn
49960 ___________________________________________________________________
49961 Name: svn:eol-style
49962    + native
49963
49964 Index: NEWS
49965 ===================================================================
49966 --- NEWS        (.../tags/lighttpd-1.4.11)      (revision 1159)
49967 +++ NEWS        (.../branches/lighttpd-merge-1.4.x)     (revision 1159)
49968 @@ -3,6 +3,23 @@
49969  NEWS
49970  ====
49971  
49972 +- 1.4.12 - 2006-..-..
49973 +
49974 +  * added handling of Content-Range to PUT requests in mod_webdav
49975 +  * added handling of ETag and If-Modified-Since to mod_compress if 
49976 +    cache-dir is not set
49977 +  * added experimental LOCK support for mod_webdav 
49978 +  * added support for X-Sendfile as addition to X-LIGHTTPD-send-file.
49979 +    This allows compatibility with mod_xsendfile for apache
49980 +    (http://celebnamer.celebworld.ws/stuff/mod_xsendfile/)
49981 +  * fixed handling of If-Modified-Since if Etag is not set
49982 +  * fixed hanging fastcgi connections
49983 +  * fixed stalling SSL POST requests 
49984 +  * fixed round-robin load-balancing in mod_proxy
49985 +  * TODO: add fail-over to mod-proxy
49986 +  * TODO: fix CACHE_HIT/MISS in mod_cml
49987 +  * TODO: finish LOCK/UNLOCK in mod_webdav
49988 +
49989  - 1.4.11 - 2006-03-09
49990  
49991    * added ability to specify which ip address spawn-fci listens on 
49992
49993 Property changes on: NEWS
49994 ___________________________________________________________________
49995 Name: svn:eol-style
49996    + native
49997
49998
49999 Property changes on: .cvsignore
50000 ___________________________________________________________________
50001 Name: svn:eol-style
50002    + native
50003
50004
50005 Property changes on: lighttpd.spec.in
50006 ___________________________________________________________________
50007 Name: svn:eol-style
50008    + native
50009
50010
50011 Property changes on: .
50012 ___________________________________________________________________
50013 Name: svn:ignore
50014    - Makefile
50015 Makefile.in
50016 configure
50017 depcomp
50018 config.*
50019 lighttpd.spec
50020 mkinstalldirs
50021 distribute.sh
50022 autom4te.cache
50023 libtool
50024 missing
50025 aclocal.m4
50026 install-sh
50027 compile
50028 ltmain.sh
50029 stamp-h1
50030
50031    + Makefile
50032 Makefile.in
50033 configure
50034 depcomp
50035 config.*
50036 lighttpd.spec
50037 mkinstalldirs
50038 distribute.sh
50039 autom4te.cache
50040 libtool
50041 missing
50042 aclocal.m4
50043 install-sh
50044 compile
50045 ltmain.sh
50046 stamp-h1
50047 TAGS
50048 tags
50049
50050 Name: svk:merge
50051    + 4e593b4a-acb2-b240-a177-dc497f6e1bd5:/lighttpd/lighttpd-1.4.x-win32:631
50052
This page took 4.409166 seconds and 4 git commands to generate.