diff options
author | Arno Töll <arno@debian.org> | 2012-11-21 23:03:50 +0100 |
---|---|---|
committer | Arno Töll <arno@debian.org> | 2012-11-21 23:03:50 +0100 |
commit | 3f9e670856f606be4d9899e2d2a9ed4708575f10 (patch) | |
tree | fddace81dd1581e52f8ce144ac05a718686e6bf0 | |
parent | ec0b51649cd99420792df2352b02dc949f8f293b (diff) | |
download | lighttpd-3f9e670856f606be4d9899e2d2a9ed4708575f10.tar.gz |
Imported Upstream version 1.4.18upstream/1.4.18
-rw-r--r-- | NEWS | 11 | ||||
-rwxr-xr-x | configure | 20 | ||||
-rw-r--r-- | configure.in | 2 | ||||
-rw-r--r-- | cygwin/lighttpd.README | 10 | ||||
-rw-r--r-- | lighttpd.spec | 2 | ||||
-rw-r--r-- | openwrt/control | 4 | ||||
-rw-r--r-- | openwrt/lighttpd.mk | 2 | ||||
-rw-r--r-- | src/Makefile.am | 6 | ||||
-rw-r--r-- | src/Makefile.in | 18 | ||||
-rw-r--r-- | src/configparser.c | 97 | ||||
-rw-r--r-- | src/configparser.y | 1 | ||||
-rw-r--r-- | src/connections.c | 5 | ||||
-rw-r--r-- | src/http_auth.c | 6 | ||||
-rw-r--r-- | src/lighttpd-angel.c | 154 | ||||
-rw-r--r-- | src/mod_fastcgi.c | 89 | ||||
-rw-r--r-- | src/mod_mysql_vhost.c | 2 | ||||
-rw-r--r-- | src/server.c | 84 | ||||
-rwxr-xr-x | tests/mod-redirect.t | 10 |
18 files changed, 397 insertions, 126 deletions
@@ -3,7 +3,18 @@ NEWS ==== +- 1.4.18 - 2007-09-09 + + * fixed compile error on IRIX 6.5.x on prctl() (#1333) + * fixed forwarding a SIGINT and SIGHUP when using max-workers (#902) + * fixed FastCGI header overrun in mod_fastcgi (reported by mattias@secweb.se) + * fixed hanging redirects with keep-alive due to missing + "Content-Length: 0" headers + * fixed crashing when using undefined environment variables in the config + * fixed compilation of mod_mysql_vhost on irix (#1341) + - 1.4.17 - 2007-08-29 + * added dir-listing.set-footer in mod_dirlisting (#1277) * added sending UID and PID for SIGTERM and SIGINT to the logs * fixed hardcoded font-sizes in mod_dirlisting (#1267) @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.61 for lighttpd 1.4.17. +# Generated by GNU Autoconf 2.61 for lighttpd 1.4.18. # # Report bugs to <jan@kneschke.de>. # @@ -728,8 +728,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='lighttpd' PACKAGE_TARNAME='lighttpd' -PACKAGE_VERSION='1.4.17' -PACKAGE_STRING='lighttpd 1.4.17' +PACKAGE_VERSION='1.4.18' +PACKAGE_STRING='lighttpd 1.4.18' PACKAGE_BUGREPORT='jan@kneschke.de' ac_unique_file="src/server.c" @@ -1440,7 +1440,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures lighttpd 1.4.17 to adapt to many kinds of systems. +\`configure' configures lighttpd 1.4.18 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1511,7 +1511,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of lighttpd 1.4.17:";; + short | recursive ) echo "Configuration of lighttpd 1.4.18:";; esac cat <<\_ACEOF @@ -1645,7 +1645,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -lighttpd configure 1.4.17 +lighttpd configure 1.4.18 generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -1659,7 +1659,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by lighttpd $as_me 1.4.17, which was +It was created by lighttpd $as_me 1.4.18, which was generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ @@ -2478,7 +2478,7 @@ fi # Define the identity of the package. PACKAGE='lighttpd' - VERSION='1.4.17' + VERSION='1.4.18' cat >>confdefs.h <<_ACEOF @@ -28619,7 +28619,7 @@ exec 6>&1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by lighttpd $as_me 1.4.17, which was +This file was extended by lighttpd $as_me 1.4.18, which was generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -28672,7 +28672,7 @@ Report bugs to <bug-autoconf@gnu.org>." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -lighttpd config.status 1.4.17 +lighttpd config.status 1.4.18 configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" diff --git a/configure.in b/configure.in index 2dd6cb1..f9189ac 100644 --- a/configure.in +++ b/configure.in @@ -1,7 +1,7 @@ # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ(2.57) -AC_INIT(lighttpd, 1.4.17, jan@kneschke.de) +AC_INIT(lighttpd, 1.4.18, jan@kneschke.de) AC_CONFIG_SRCDIR([src/server.c]) AC_CANONICAL_TARGET diff --git a/cygwin/lighttpd.README b/cygwin/lighttpd.README index bfa3631..8fc9339 100644 --- a/cygwin/lighttpd.README +++ b/cygwin/lighttpd.README @@ -31,17 +31,17 @@ Canonical download: ------------------------------------ Build instructions: - unpack lighttpd-1.4.17-<REL>-src.tar.bz2 + unpack lighttpd-1.4.18-<REL>-src.tar.bz2 if you use setup to install this src package, it will be unpacked under /usr/src automatically cd /usr/src - ./lighttpd-1.4.17-<REL>.sh all + ./lighttpd-1.4.18-<REL>.sh all This will create: - /usr/src/lighttpd-1.4.17-<REL>.tar.bz2 - /usr/src/lighttpd-1.4.17-<REL>-src.tar.bz2 + /usr/src/lighttpd-1.4.18-<REL>.tar.bz2 + /usr/src/lighttpd-1.4.18-<REL>-src.tar.bz2 -Or use './lighttpd-1.4.17-<REL>.sh prep' to get a patched source directory +Or use './lighttpd-1.4.18-<REL>.sh prep' to get a patched source directory ------------------------------------------- diff --git a/lighttpd.spec b/lighttpd.spec index 6f5543f..1a32b5d 100644 --- a/lighttpd.spec +++ b/lighttpd.spec @@ -1,6 +1,6 @@ Summary: A fast webserver with minimal memory-footprint (lighttpd) Name: lighttpd -Version: 1.4.17 +Version: 1.4.18 Release: 1 Source: http://jan.kneschke.de/projects/lighttpd/download/lighttpd-%version.tar.gz Packager: Jan Kneschke <jan@kneschke.de> diff --git a/openwrt/control b/openwrt/control index 21be30a..7dee2c3 100644 --- a/openwrt/control +++ b/openwrt/control @@ -1,8 +1,8 @@ Package: lighttpd -Version: 1.4.17 +Version: 1.4.18 Architecture: mipsel Maintainer: Jan Kneschke <jan@kneschke.de> -Source: http://jan.kneschke.de/projects/lighttpd/download/lighttpd-1.4.17.tar.gz +Source: http://jan.kneschke.de/projects/lighttpd/download/lighttpd-1.4.18.tar.gz Section: net Priority: optional Depends: diff --git a/openwrt/lighttpd.mk b/openwrt/lighttpd.mk index eb917c3..71cf0c7 100644 --- a/openwrt/lighttpd.mk +++ b/openwrt/lighttpd.mk @@ -10,7 +10,7 @@ # For this example we'll use a fairly simple package that compiles easily # and has sources available for download at sourceforge -LIGHTTPD=lighttpd-1.4.17 +LIGHTTPD=lighttpd-1.4.18 LIGHTTPD_TARGET=.built LIGHTTPD_DIR=$(BUILD_DIR)/$(LIGHTTPD) LIGHTTPD_IPK=$(BUILD_DIR)/$(LIGHTTPD)_mipsel.ipk diff --git a/src/Makefile.am b/src/Makefile.am index 3af10c8..24967c8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,12 +1,14 @@ AM_CFLAGS = $(FAM_CFLAGS) noinst_PROGRAMS=proc_open lemon # simple-fcgi #graphic evalo bench ajp ssl error_test adserver gen-license -sbin_PROGRAMS=lighttpd +sbin_PROGRAMS=lighttpd lighttpd-angel bin_PROGRAMS=spawn-fcgi LEMON=$(top_builddir)/src/lemon lemon_SOURCES=lemon.c +lighttpd_angel_SOURCES=lighttpd-angel.c + #simple_fcgi_SOURCES=simple-fcgi.c #simple_fcgi_LDADD=-lfcgi @@ -254,7 +256,7 @@ hdr = server.h buffer.h network.h log.h keyvalue.h \ splaytree.h proc_open.h status_counter.h \ mod_magnet_cache.h -DEFS= @DEFS@ -DLIBRARY_DIR="\"$(libdir)\"" +DEFS= @DEFS@ -DLIBRARY_DIR="\"$(libdir)\"" -DSBIN_DIR="\"$(sbindir)\"" lighttpd_SOURCES = $(src) lighttpd_LDADD = $(PCRE_LIB) $(DL_LIB) $(SENDFILE_LIB) $(ATTR_LIB) $(common_libadd) $(SSL_LIB) $(FAM_LIBS) diff --git a/src/Makefile.in b/src/Makefile.in index 3d8194a..2952518 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -36,7 +36,7 @@ build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ noinst_PROGRAMS = proc_open$(EXEEXT) lemon$(EXEEXT) -sbin_PROGRAMS = lighttpd$(EXEEXT) +sbin_PROGRAMS = lighttpd$(EXEEXT) lighttpd-angel$(EXEEXT) bin_PROGRAMS = spawn-fcgi$(EXEEXT) # if the linker doesn't allow referencing symbols of the binary @@ -373,6 +373,9 @@ lighttpd_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ lighttpd_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(lighttpd_LDFLAGS) \ $(LDFLAGS) -o $@ +am_lighttpd_angel_OBJECTS = lighttpd-angel.$(OBJEXT) +lighttpd_angel_OBJECTS = $(am_lighttpd_angel_OBJECTS) +lighttpd_angel_LDADD = $(LDADD) am_proc_open_OBJECTS = proc_open-proc_open.$(OBJEXT) \ proc_open-buffer.$(OBJEXT) proc_open_OBJECTS = $(am_proc_open_OBJECTS) @@ -409,7 +412,8 @@ SOURCES = $(liblightcomp_la_SOURCES) $(mod_access_la_SOURCES) \ $(mod_status_la_SOURCES) $(mod_trigger_b4_dl_la_SOURCES) \ $(mod_userdir_la_SOURCES) $(mod_usertrack_la_SOURCES) \ $(mod_webdav_la_SOURCES) $(lemon_SOURCES) $(lighttpd_SOURCES) \ - $(proc_open_SOURCES) $(spawn_fcgi_SOURCES) + $(lighttpd_angel_SOURCES) $(proc_open_SOURCES) \ + $(spawn_fcgi_SOURCES) DIST_SOURCES = $(am__liblightcomp_la_SOURCES_DIST) \ $(mod_access_la_SOURCES) $(mod_accesslog_la_SOURCES) \ $(mod_alias_la_SOURCES) $(mod_auth_la_SOURCES) \ @@ -428,7 +432,8 @@ DIST_SOURCES = $(am__liblightcomp_la_SOURCES_DIST) \ $(mod_trigger_b4_dl_la_SOURCES) $(mod_userdir_la_SOURCES) \ $(mod_usertrack_la_SOURCES) $(mod_webdav_la_SOURCES) \ $(lemon_SOURCES) $(am__lighttpd_SOURCES_DIST) \ - $(proc_open_SOURCES) $(spawn_fcgi_SOURCES) + $(lighttpd_angel_SOURCES) $(proc_open_SOURCES) \ + $(spawn_fcgi_SOURCES) HEADERS = $(noinst_HEADERS) ETAGS = etags CTAGS = ctags @@ -453,7 +458,7 @@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DLIBRARY_DIR="\"$(libdir)\"" +DEFS = @DEFS@ -DLIBRARY_DIR="\"$(libdir)\"" -DSBIN_DIR="\"$(sbindir)\"" DEPDIR = @DEPDIR@ DL_LIB = @DL_LIB@ ECHO = @ECHO@ @@ -573,6 +578,7 @@ top_srcdir = @top_srcdir@ AM_CFLAGS = $(FAM_CFLAGS) LEMON = $(top_builddir)/src/lemon lemon_SOURCES = lemon.c +lighttpd_angel_SOURCES = lighttpd-angel.c common_src = buffer.c log.c \ keyvalue.c chunk.c \ http_chunk.c stream.c fdevent.c \ @@ -945,6 +951,9 @@ lemon$(EXEEXT): $(lemon_OBJECTS) $(lemon_DEPENDENCIES) lighttpd$(EXEEXT): $(lighttpd_OBJECTS) $(lighttpd_DEPENDENCIES) @rm -f lighttpd$(EXEEXT) $(lighttpd_LINK) $(lighttpd_OBJECTS) $(lighttpd_LDADD) $(LIBS) +lighttpd-angel$(EXEEXT): $(lighttpd_angel_OBJECTS) $(lighttpd_angel_DEPENDENCIES) + @rm -f lighttpd-angel$(EXEEXT) + $(LINK) $(lighttpd_angel_OBJECTS) $(lighttpd_angel_LDADD) $(LIBS) proc_open$(EXEEXT): $(proc_open_OBJECTS) $(proc_open_DEPENDENCIES) @rm -f proc_open$(EXEEXT) $(LINK) $(proc_open_OBJECTS) $(proc_open_LDADD) $(LIBS) @@ -1029,6 +1038,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblightcomp_la-stat_cache.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblightcomp_la-status_counter.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblightcomp_la-stream.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lighttpd-angel.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_access.Plo@am__quote@ diff --git a/src/configparser.c b/src/configparser.c index 292cff0..363b395 100644 --- a/src/configparser.c +++ b/src/configparser.c @@ -941,6 +941,7 @@ static void yy_reduce( case 14: #line 232 "./configparser.y" { + yygotominor.yy41 = NULL; if (strncmp(yymsp[0].minor.yy43->ptr, "env.", sizeof("env.") - 1) == 0) { char *env; @@ -965,59 +966,59 @@ static void yy_reduce( buffer_free(yymsp[0].minor.yy43); yymsp[0].minor.yy43 = NULL; } -#line 968 "configparser.c" +#line 969 "configparser.c" break; case 15: -#line 258 "./configparser.y" +#line 259 "./configparser.y" { yygotominor.yy41 = (data_unset *)data_string_init(); buffer_copy_string_buffer(((data_string *)(yygotominor.yy41))->value, yymsp[0].minor.yy0); buffer_free(yymsp[0].minor.yy0); yymsp[0].minor.yy0 = NULL; } -#line 978 "configparser.c" +#line 979 "configparser.c" break; case 16: -#line 265 "./configparser.y" +#line 266 "./configparser.y" { yygotominor.yy41 = (data_unset *)data_integer_init(); ((data_integer *)(yygotominor.yy41))->value = strtol(yymsp[0].minor.yy0->ptr, NULL, 10); buffer_free(yymsp[0].minor.yy0); yymsp[0].minor.yy0 = NULL; } -#line 988 "configparser.c" +#line 989 "configparser.c" break; case 17: -#line 271 "./configparser.y" +#line 272 "./configparser.y" { yygotominor.yy41 = (data_unset *)data_array_init(); array_free(((data_array *)(yygotominor.yy41))->value); ((data_array *)(yygotominor.yy41))->value = yymsp[0].minor.yy40; yymsp[0].minor.yy40 = NULL; } -#line 998 "configparser.c" +#line 999 "configparser.c" break; case 18: -#line 277 "./configparser.y" +#line 278 "./configparser.y" { yygotominor.yy40 = array_init(); } -#line 1005 "configparser.c" +#line 1006 "configparser.c" yy_destructor(8,&yymsp[-1].minor); yy_destructor(9,&yymsp[0].minor); break; case 19: -#line 280 "./configparser.y" +#line 281 "./configparser.y" { yygotominor.yy40 = yymsp[-1].minor.yy40; yymsp[-1].minor.yy40 = NULL; } -#line 1015 "configparser.c" +#line 1016 "configparser.c" yy_destructor(8,&yymsp[-2].minor); yy_destructor(9,&yymsp[0].minor); break; case 20: -#line 285 "./configparser.y" +#line 286 "./configparser.y" { if (buffer_is_empty(yymsp[0].minor.yy41->key) || NULL == array_get_element(yymsp[-2].minor.yy40, yymsp[0].minor.yy41->key->ptr)) { @@ -1034,37 +1035,37 @@ static void yy_reduce( yygotominor.yy40 = yymsp[-2].minor.yy40; yymsp[-2].minor.yy40 = NULL; } -#line 1037 "configparser.c" +#line 1038 "configparser.c" yy_destructor(10,&yymsp[-1].minor); break; case 21: -#line 302 "./configparser.y" +#line 303 "./configparser.y" { yygotominor.yy40 = yymsp[-1].minor.yy40; yymsp[-1].minor.yy40 = NULL; } -#line 1046 "configparser.c" +#line 1047 "configparser.c" yy_destructor(10,&yymsp[0].minor); break; case 22: -#line 307 "./configparser.y" +#line 308 "./configparser.y" { yygotominor.yy40 = array_init(); array_insert_unique(yygotominor.yy40, yymsp[0].minor.yy41); yymsp[0].minor.yy41 = NULL; } -#line 1056 "configparser.c" +#line 1057 "configparser.c" break; case 23: -#line 313 "./configparser.y" +#line 314 "./configparser.y" { yygotominor.yy41 = yymsp[0].minor.yy41; yymsp[0].minor.yy41 = NULL; } -#line 1064 "configparser.c" +#line 1065 "configparser.c" break; case 24: -#line 317 "./configparser.y" +#line 318 "./configparser.y" { buffer_copy_string_buffer(yymsp[0].minor.yy41->key, yymsp[-2].minor.yy43); buffer_free(yymsp[-2].minor.yy43); @@ -1073,7 +1074,7 @@ static void yy_reduce( yygotominor.yy41 = yymsp[0].minor.yy41; yymsp[0].minor.yy41 = NULL; } -#line 1076 "configparser.c" +#line 1077 "configparser.c" yy_destructor(11,&yymsp[-1].minor); break; case 25: @@ -1082,18 +1083,18 @@ static void yy_reduce( case 26: break; case 27: -#line 329 "./configparser.y" +#line 330 "./configparser.y" { data_config *dc; dc = (data_config *)array_get_element(ctx->srv->config_context, "global"); assert(dc); configparser_push(ctx, dc, 0); } -#line 1092 "configparser.c" +#line 1093 "configparser.c" yy_destructor(12,&yymsp[0].minor); break; case 28: -#line 336 "./configparser.y" +#line 337 "./configparser.y" { data_config *cur; @@ -1104,14 +1105,14 @@ static void yy_reduce( yygotominor.yy0 = cur; } -#line 1107 "configparser.c" +#line 1108 "configparser.c" /* No destructor defined for globalstart */ yy_destructor(13,&yymsp[-2].minor); /* No destructor defined for metalines */ yy_destructor(14,&yymsp[0].minor); break; case 29: -#line 347 "./configparser.y" +#line 348 "./configparser.y" { assert(yymsp[-3].minor.yy78->context_ndx < yymsp[0].minor.yy78->context_ndx); yymsp[0].minor.yy78->prev = yymsp[-3].minor.yy78; @@ -1120,20 +1121,20 @@ static void yy_reduce( yymsp[-3].minor.yy78 = NULL; yymsp[0].minor.yy78 = NULL; } -#line 1123 "configparser.c" +#line 1124 "configparser.c" /* No destructor defined for eols */ yy_destructor(15,&yymsp[-1].minor); break; case 30: -#line 356 "./configparser.y" +#line 357 "./configparser.y" { yygotominor.yy78 = yymsp[0].minor.yy78; yymsp[0].minor.yy78 = NULL; } -#line 1133 "configparser.c" +#line 1134 "configparser.c" break; case 31: -#line 361 "./configparser.y" +#line 362 "./configparser.y" { data_config *cur; @@ -1144,14 +1145,14 @@ static void yy_reduce( yygotominor.yy78 = cur; } -#line 1147 "configparser.c" +#line 1148 "configparser.c" /* No destructor defined for context */ yy_destructor(13,&yymsp[-2].minor); /* No destructor defined for metalines */ yy_destructor(14,&yymsp[0].minor); break; case 32: -#line 372 "./configparser.y" +#line 373 "./configparser.y" { data_config *dc; buffer *b, *rvalue, *op; @@ -1287,45 +1288,45 @@ static void yy_reduce( yymsp[0].minor.yy41->free(yymsp[0].minor.yy41); yymsp[0].minor.yy41 = NULL; } -#line 1290 "configparser.c" +#line 1291 "configparser.c" yy_destructor(16,&yymsp[-6].minor); yy_destructor(18,&yymsp[-4].minor); yy_destructor(19,&yymsp[-2].minor); break; case 33: -#line 507 "./configparser.y" +#line 508 "./configparser.y" { yygotominor.yy27 = CONFIG_COND_EQ; } -#line 1300 "configparser.c" +#line 1301 "configparser.c" yy_destructor(20,&yymsp[0].minor); break; case 34: -#line 510 "./configparser.y" +#line 511 "./configparser.y" { yygotominor.yy27 = CONFIG_COND_MATCH; } -#line 1308 "configparser.c" +#line 1309 "configparser.c" yy_destructor(21,&yymsp[0].minor); break; case 35: -#line 513 "./configparser.y" +#line 514 "./configparser.y" { yygotominor.yy27 = CONFIG_COND_NE; } -#line 1316 "configparser.c" +#line 1317 "configparser.c" yy_destructor(22,&yymsp[0].minor); break; case 36: -#line 516 "./configparser.y" +#line 517 "./configparser.y" { yygotominor.yy27 = CONFIG_COND_NOMATCH; } -#line 1324 "configparser.c" +#line 1325 "configparser.c" yy_destructor(23,&yymsp[0].minor); break; case 37: -#line 520 "./configparser.y" +#line 521 "./configparser.y" { yygotominor.yy43 = NULL; if (ctx->ok) { @@ -1342,10 +1343,10 @@ static void yy_reduce( yymsp[0].minor.yy41->free(yymsp[0].minor.yy41); yymsp[0].minor.yy41 = NULL; } -#line 1345 "configparser.c" +#line 1346 "configparser.c" break; case 38: -#line 537 "./configparser.y" +#line 538 "./configparser.y" { if (ctx->ok) { if (0 != config_parse_file(ctx->srv, ctx, yymsp[0].minor.yy43->ptr)) { @@ -1355,11 +1356,11 @@ static void yy_reduce( yymsp[0].minor.yy43 = NULL; } } -#line 1358 "configparser.c" +#line 1359 "configparser.c" yy_destructor(24,&yymsp[-1].minor); break; case 39: -#line 547 "./configparser.y" +#line 548 "./configparser.y" { if (ctx->ok) { if (0 != config_parse_cmd(ctx->srv, ctx, yymsp[0].minor.yy43->ptr)) { @@ -1369,7 +1370,7 @@ static void yy_reduce( yymsp[0].minor.yy43 = NULL; } } -#line 1372 "configparser.c" +#line 1373 "configparser.c" yy_destructor(25,&yymsp[-1].minor); break; }; @@ -1403,7 +1404,7 @@ static void yy_parse_failed( ctx->ok = 0; -#line 1406 "configparser.c" +#line 1407 "configparser.c" configparserARG_STORE; /* Suppress warning about unused %extra_argument variable */ } diff --git a/src/configparser.y b/src/configparser.y index b5bc785..30f5fd9 100644 --- a/src/configparser.y +++ b/src/configparser.y @@ -230,6 +230,7 @@ expression(A) ::= value(B). { } value(A) ::= key(B). { + A = NULL; if (strncmp(B->ptr, "env.", sizeof("env.") - 1) == 0) { char *env; diff --git a/src/connections.c b/src/connections.c index 62b4d5e..94d36b4 100644 --- a/src/connections.c +++ b/src/connections.c @@ -537,7 +537,10 @@ static int connection_handle_write_prepare(server *srv, connection *con) { con->http_status == 204 || con->http_status == 304) { /* no Content-Body, no Content-Length */ - } else if (qlen > 0) { + } else if (qlen >= 0) { + /* qlen = 0 is important for Redirects (301, ...) as they MAY have + * a content. Browsers are waiting for a Content otherwise + */ buffer_copy_off_t(srv->tmp_buf, chunkqueue_length(con->write_queue)); response_header_overwrite(srv, con, CONST_STR_LEN("Content-Length"), CONST_BUF_LEN(srv->tmp_buf)); diff --git a/src/http_auth.c b/src/http_auth.c index b95b79b..1bfb460 100644 --- a/src/http_auth.c +++ b/src/http_auth.c @@ -831,19 +831,17 @@ int http_auth_basic_check(server *srv, connection *con, mod_auth_plugin_data *p, username = buffer_init(); if (!base64_decode(username, realm_str)) { - buffer_free(username); - log_error_write(srv, __FILE__, __LINE__, "sb", "decodeing base64-string failed", username); + buffer_free(username); return 0; } /* r2 == user:password */ if (NULL == (pw = strchr(username->ptr, ':'))) { - buffer_free(username); - log_error_write(srv, __FILE__, __LINE__, "sb", ": is missing in", username); + buffer_free(username); return 0; } diff --git a/src/lighttpd-angel.c b/src/lighttpd-angel.c new file mode 100644 index 0000000..a6e3741 --- /dev/null +++ b/src/lighttpd-angel.c @@ -0,0 +1,154 @@ +/** + * angel process for lighttpd + * + * the purpose is the run as root all the time and handle: + * - restart on crash + * - spawn on HUP to allow graceful restart + * - ... + * + * it has to stay safe and small to be trustable + */ + +#include <sys/wait.h> + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <time.h> +#include <signal.h> + +#define BINPATH SBIN_DIR"/lighttpd" + +static siginfo_t last_sigterm_info; +static siginfo_t last_sighup_info; + +static volatile sig_atomic_t start_process = 1; +static volatile sig_atomic_t graceful_restart = 0; +static volatile pid_t pid = -1; + +static void sigaction_handler(int sig, siginfo_t *si, void *context) { + int exitcode; + + switch (sig) { + case SIGINT: + case SIGTERM: + memcpy(&last_sigterm_info, si, sizeof(*si)); + + /** forward the sig to the child */ + kill(pid, sig); + break; + case SIGHUP: /** do a graceful restart */ + memcpy(&last_sighup_info, si, sizeof(*si)); + + /** do a graceful shutdown on the main process and start a new child */ + kill(pid, SIGINT); + + usleep(5 * 1000); /** wait 5 microsec */ + + start_process = 1; + break; + case SIGCHLD: + /** a child died, de-combie it */ + wait(&exitcode); + break; + } +} + +int main(int argc, char **argv) { + int is_shutdown = 0; + struct sigaction act; + + /** + * we are running as root BEWARE + */ + + memset(&act, 0, sizeof(act)); + act.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &act, NULL); + sigaction(SIGUSR1, &act, NULL); + + act.sa_sigaction = sigaction_handler; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_SIGINFO; + + sigaction(SIGINT, &act, NULL); + sigaction(SIGTERM, &act, NULL); + sigaction(SIGHUP, &act, NULL); + sigaction(SIGALRM, &act, NULL); + sigaction(SIGCHLD, &act, NULL); + + /* check that the compiled in path has the right user, + * + * BEWARE: there is a race between the check here and the exec later + */ + + while (!is_shutdown) { + int exitcode = 0; + + if (start_process) { + pid = fork(); + + if (0 == pid) { + /* i'm the child */ + + argv[0] = BINPATH; + + execvp(BINPATH, argv); + + exit(1); + } else if (-1 == pid) { + /** error */ + + return -1; + } + + /* I'm the angel */ + start_process = 0; + } + + if ((pid_t)-1 == waitpid(pid, &exitcode, 0)) { + switch (errno) { + case EINTR: + /* someone sent a signal ... + * do we have to shutdown or restart the process */ + break; + case ECHILD: + /** + * make sure we are not in a race between the signal handler + * and the process restart */ + if (!start_process) is_shutdown = 1; + break; + default: + break; + } + } else { + /** process went away */ + + if (WIFEXITED(exitcode)) { + /** normal exit */ + + is_shutdown = 1; + + fprintf(stderr, "%s.%d: child (pid=%d) exited normally with exitcode: %d\n", + __FILE__, __LINE__, + pid, + WEXITSTATUS(exitcode)); + + } else if (WIFSIGNALED(exitcode)) { + /** got a signal */ + + fprintf(stderr, "%s.%d: child (pid=%d) exited unexpectedly with signal %d, restarting\n", + __FILE__, __LINE__, + pid, + WTERMSIG(exitcode)); + + start_process = 1; + } + } + } + + return 0; +} + diff --git a/src/mod_fastcgi.c b/src/mod_fastcgi.c index e0dda30..75b52ad 100644 --- a/src/mod_fastcgi.c +++ b/src/mod_fastcgi.c @@ -49,6 +49,12 @@ #include <sys/wait.h> #endif +#define FCGI_ENV_ADD_CHECK(ret, con) \ + if (ret == -1) { \ + con->http_status = 400; \ + con->file_finished = 1; \ + return -1; \ + }; /* * @@ -1571,6 +1577,21 @@ static int fcgi_env_add(buffer *env, const char *key, size_t key_len, const char len += key_len > 127 ? 4 : 1; len += val_len > 127 ? 4 : 1; + if (env->used + len >= FCGI_MAX_LENGTH) { + /** + * we can't append more headers, ignore it + */ + return -1; + } + + /** + * field length can be 31bit max + * + * HINT: this can't happen as FCGI_MAX_LENGTH is only 16bit + */ + if (key_len > 0x7fffffff) key_len = 0x7fffffff; + if (val_len > 0x7fffffff) val_len = 0x7fffffff; + buffer_prepare_append(env, len); if (key_len > 127) { @@ -1600,6 +1621,8 @@ static int fcgi_env_add(buffer *env, const char *key, size_t key_len, const char } static int fcgi_header(FCGI_Header * header, unsigned char type, size_t request_id, int contentLength, unsigned char paddingLength) { + assert(contentLength <= FCGI_MAX_LENGTH); + header->version = FCGI_VERSION_1; header->type = type; header->requestIdB0 = request_id & 0xff; @@ -1754,7 +1777,7 @@ static int fcgi_env_add_request_headers(server *srv, connection *con, plugin_dat } srv->tmp_buf->ptr[srv->tmp_buf->used++] = '\0'; - fcgi_env_add(p->fcgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value)); + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value)),con); } } @@ -1781,7 +1804,7 @@ static int fcgi_env_add_request_headers(server *srv, connection *con, plugin_dat } srv->tmp_buf->ptr[srv->tmp_buf->used++] = '\0'; - fcgi_env_add(p->fcgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value)); + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_BUF_LEN(srv->tmp_buf), CONST_BUF_LEN(ds->value)), con); } } @@ -1825,10 +1848,10 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) { buffer_prepare_copy(p->fcgi_env, 1024); - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_NAME"/"PACKAGE_VERSION)); + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_NAME"/"PACKAGE_VERSION)),con) if (con->server_name->used) { - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_NAME"), CONST_BUF_LEN(con->server_name)); + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_NAME"), CONST_BUF_LEN(con->server_name)),con) } else { #ifdef HAVE_IPV6 s = inet_ntop(srv_sock->addr.plain.sa_family, @@ -1839,10 +1862,10 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) { #else s = inet_ntoa(srv_sock->addr.ipv4.sin_addr); #endif - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_NAME"), s, strlen(s)); + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_NAME"), s, strlen(s)),con) } - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("GATEWAY_INTERFACE"), CONST_STR_LEN("CGI/1.1")); + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("GATEWAY_INTERFACE"), CONST_STR_LEN("CGI/1.1")),con) LI_ltostr(buf, #ifdef HAVE_IPV6 @@ -1852,7 +1875,7 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) { #endif ); - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_PORT"), buf, strlen(buf)); + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_PORT"), buf, strlen(buf)),con) /* get the server-side of the connection to the client */ our_addr_len = sizeof(our_addr); @@ -1862,7 +1885,7 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) { } else { s = inet_ntop_cache_get_ip(srv, &(our_addr)); } - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_ADDR"), s, strlen(s)); + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_ADDR"), s, strlen(s)),con) LI_ltostr(buf, #ifdef HAVE_IPV6 @@ -1872,10 +1895,10 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) { #endif ); - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REMOTE_PORT"), buf, strlen(buf)); + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REMOTE_PORT"), buf, strlen(buf)),con) s = inet_ntop_cache_get_ip(srv, &(con->dst_addr)); - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REMOTE_ADDR"), s, strlen(s)); + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REMOTE_ADDR"), s, strlen(s)),con) if (!buffer_is_empty(con->authed_user)) { /* AUTH_TYPE fix by Troy Kruthoff (tkruthoff@gmail.com) @@ -1891,7 +1914,7 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) { char *http_authorization = NULL; data_string *ds; - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REMOTE_USER"), CONST_BUF_LEN(con->authed_user)); + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REMOTE_USER"), CONST_BUF_LEN(con->authed_user)),con) if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Authorization"))) { http_authorization = ds->value->ptr; @@ -1915,7 +1938,7 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) { /* request.content_length < SSIZE_MAX, see request.c */ LI_ltostr(buf, con->request.content_length); - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("CONTENT_LENGTH"), buf, strlen(buf)); + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("CONTENT_LENGTH"), buf, strlen(buf)),con) } if (host->mode != FCGI_AUTHORIZER) { @@ -1926,10 +1949,10 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) { * For AUTHORIZER mode these headers should be omitted. */ - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path)); + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SCRIPT_NAME"), CONST_BUF_LEN(con->uri.path)),con) if (!buffer_is_empty(con->request.pathinfo)) { - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("PATH_INFO"), CONST_BUF_LEN(con->request.pathinfo)); + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("PATH_INFO"), CONST_BUF_LEN(con->request.pathinfo)),con) /* PATH_TRANSLATED is only defined if PATH_INFO is set */ @@ -1939,9 +1962,9 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) { buffer_copy_string_buffer(p->path, con->physical.doc_root); } buffer_append_string_buffer(p->path, con->request.pathinfo); - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("PATH_TRANSLATED"), CONST_BUF_LEN(p->path)); + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("PATH_TRANSLATED"), CONST_BUF_LEN(p->path)),con) } else { - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("PATH_INFO"), CONST_STR_LEN("")); + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("PATH_INFO"), CONST_STR_LEN("")),con) } } @@ -1962,8 +1985,8 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) { buffer_copy_string_buffer(p->path, host->docroot); buffer_append_string_buffer(p->path, con->uri.path); - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path)); - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(host->docroot)); + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path)),con) + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(host->docroot)),con) } else { buffer_copy_string_buffer(p->path, con->physical.path); @@ -1975,8 +1998,8 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) { buffer_append_string_buffer(p->path, con->request.pathinfo); } - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path)); - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(con->physical.doc_root)); + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SCRIPT_FILENAME"), CONST_BUF_LEN(p->path)),con) + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("DOCUMENT_ROOT"), CONST_BUF_LEN(con->physical.doc_root)),con) } if (host->strip_request_uri->used > 1) { @@ -2002,34 +2025,34 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) { con->request.orig_uri->ptr + (host->strip_request_uri->used - 2), con->request.orig_uri->used - (host->strip_request_uri->used - 2)); } else { - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REQUEST_URI"), CONST_BUF_LEN(con->request.orig_uri)); + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REQUEST_URI"), CONST_BUF_LEN(con->request.orig_uri)),con) } } else { - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REQUEST_URI"), CONST_BUF_LEN(con->request.orig_uri)); + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REQUEST_URI"), CONST_BUF_LEN(con->request.orig_uri)),con) } if (!buffer_is_equal(con->request.uri, con->request.orig_uri)) { - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REDIRECT_URI"), CONST_BUF_LEN(con->request.uri)); + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REDIRECT_URI"), CONST_BUF_LEN(con->request.uri)),con) } if (!buffer_is_empty(con->uri.query)) { - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("QUERY_STRING"), CONST_BUF_LEN(con->uri.query)); + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("QUERY_STRING"), CONST_BUF_LEN(con->uri.query)),con) } else { - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("QUERY_STRING"), CONST_STR_LEN("")); + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("QUERY_STRING"), CONST_STR_LEN("")),con) } s = get_http_method_name(con->request.http_method); - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REQUEST_METHOD"), s, strlen(s)); - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REDIRECT_STATUS"), CONST_STR_LEN("200")); /* if php is compiled with --force-redirect */ + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REQUEST_METHOD"), s, strlen(s)),con) + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REDIRECT_STATUS"), CONST_STR_LEN("200")),con) /* if php is compiled with --force-redirect */ s = get_http_version_name(con->request.http_version); - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_PROTOCOL"), s, strlen(s)); + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_PROTOCOL"), s, strlen(s)),con) #ifdef USE_OPENSSL if (srv_sock->is_ssl) { - fcgi_env_add(p->fcgi_env, CONST_STR_LEN("HTTPS"), CONST_STR_LEN("on")); + FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("HTTPS"), CONST_STR_LEN("on")),con) } #endif - fcgi_env_add_request_headers(srv, con, p); + FCGI_ENV_ADD_CHECK(fcgi_env_add_request_headers(srv, con, p), con); fcgi_header(&(header), FCGI_PARAMS, request_id, p->fcgi_env->used, 0); buffer_append_memory(b, (const char *)&header, sizeof(header)); @@ -2924,10 +2947,8 @@ static handler_t fcgi_write_request(server *srv, handler_ctx *hctx) { } /* fall through */ - fcgi_create_env(srv, hctx, hctx->request_id); - + if (-1 == fcgi_create_env(srv, hctx, hctx->request_id)) return HANDLER_ERROR; fcgi_set_state(srv, hctx, FCGI_STATE_WRITE); - /* fall through */ case FCGI_STATE_WRITE: ret = srv->network_backend_write(srv, con, hctx->fd, hctx->wb); @@ -3109,7 +3130,7 @@ SUBREQUEST_FUNC(mod_fastcgi_handle_subrequest) { buffer_reset(con->physical.path); con->mode = DIRECT; - con->http_status = 503; + if (con->http_status != 400) con->http_status = 503; joblist_append(srv, con); /* really ? */ return HANDLER_FINISHED; diff --git a/src/mod_mysql_vhost.c b/src/mod_mysql_vhost.c index 65e7ce9..fe2b67f 100644 --- a/src/mod_mysql_vhost.c +++ b/src/mod_mysql_vhost.c @@ -222,7 +222,7 @@ SERVER_FUNC(mod_mysql_vhost_set_defaults) { s->mysql_pre = buffer_init(); s->mysql_post = buffer_init(); - if (sel->used && (qmark = index(sel->ptr, '?'))) { + if (sel->used && (qmark = strchr(sel->ptr, '?'))) { *qmark = '\0'; buffer_copy_string(s->mysql_pre, sel->ptr); buffer_copy_string(s->mysql_post, qmark+1); diff --git a/src/server.c b/src/server.c index b610cdc..132eb32 100644 --- a/src/server.c +++ b/src/server.c @@ -68,6 +68,7 @@ static volatile sig_atomic_t srv_shutdown = 0; static volatile sig_atomic_t graceful_shutdown = 0; static volatile sig_atomic_t handle_sig_alarm = 1; static volatile sig_atomic_t handle_sig_hup = 0; +static volatile sig_atomic_t forwarded_sig_hup = 0; #if defined(HAVE_SIGACTION) && defined(SA_SIGINFO) static volatile siginfo_t last_sigterm_info; @@ -94,8 +95,19 @@ static void sigaction_handler(int sig, siginfo_t *si, void *context) { handle_sig_alarm = 1; break; case SIGHUP: - handle_sig_hup = 1; - memcpy(&last_sighup_info, si, sizeof(*si)); + /** + * we send the SIGHUP to all procs in the process-group + * this includes ourself + * + * make sure we only send it once and don't create a + * infinite loop + */ + if (!forwarded_sig_hup) { + handle_sig_hup = 1; + memcpy(&last_sighup_info, si, sizeof(*si)); + } else { + forwarded_sig_hup = 0; + } break; case SIGCHLD: break; @@ -775,7 +787,10 @@ int main (int argc, char **argv) { setuid(pwd->pw_uid); } #endif -#ifdef HAVE_SYS_PRCTL_H +#if defined(HAVE_SYS_PRCTL_H) && defined(PR_SET_DUMPABLE) + /** + * on IRIX 6.5.30 they have prctl() but no DUMPABLE + */ if (srv->srvconf.enable_cores) { prctl(PR_SET_DUMPABLE, 1, 0, 0, 0); } @@ -985,7 +1000,7 @@ int main (int argc, char **argv) { num_childs = srv->srvconf.max_worker; if (num_childs > 0) { int child = 0; - while (!child && !srv_shutdown) { + while (!child && !srv_shutdown && !graceful_shutdown) { if (num_childs > 0) { switch (fork()) { case -1: @@ -1000,14 +1015,61 @@ int main (int argc, char **argv) { } else { int status; - /* ignore EINTR */ - if (-1 != wait(&status)) num_childs++; + if (-1 != wait(&status)) { + /** + * one of our workers went away + */ + num_childs++; + } else { + switch (errno) { + case EINTR: + /** + * if we receive a SIGHUP we have to close our logs ourself as we don't + * have the mainloop who can help us here + */ + if (handle_sig_hup) { + handle_sig_hup = 0; + + log_error_cycle(srv); + + /** + * forward to all procs in the process-group + * + * we also send it ourself + */ + if (!forwarded_sig_hup) { + forwarded_sig_hup = 1; + kill(0, SIGHUP); + } + } + break; + default: + break; + } + } } } - if (srv_shutdown) { - kill(0, SIGTERM); + + /** + * for the parent this is the exit-point + */ + if (!child) { + /** + * kill all children too + */ + if (graceful_shutdown) { + kill(0, SIGINT); + } else if (srv_shutdown) { + kill(0, SIGTERM); + } + + log_error_close(srv); + network_close(srv); + connections_free(srv); + plugins_free(srv); + server_free(srv); + return 0; } - if (!child) return 0; } #endif @@ -1098,9 +1160,9 @@ int main (int argc, char **argv) { #ifdef HAVE_SIGACTION log_error_write(srv, __FILE__, __LINE__, "sdsd", "logfiles cycled UID =", - last_sigterm_info.si_uid, + last_sighup_info.si_uid, "PID =", - last_sigterm_info.si_pid); + last_sighup_info.si_pid); #else log_error_write(srv, __FILE__, __LINE__, "s", "logfiles cycled"); diff --git a/tests/mod-redirect.t b/tests/mod-redirect.t index b26abc9..076a4b3 100755 --- a/tests/mod-redirect.t +++ b/tests/mod-redirect.t @@ -8,7 +8,7 @@ BEGIN { use strict; use IO::Socket; -use Test::More tests => 6; +use Test::More tests => 7; use LightyTest; my $tf = LightyTest->new(); @@ -24,6 +24,14 @@ EOF $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 301, 'Location' => 'http://localhost:'.$tf->{PORT}.'/' } ]; ok($tf->handle_http($t) == 0, 'external redirect'); +$t->{REQUEST} = ( <<EOF +GET /redirect/ HTTP/1.0 +Host: vvv.example.org +EOF + ); +$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 301, 'Location' => 'http://localhost:'.$tf->{PORT}.'/', 'Content-Length' => '0' } ]; +ok($tf->handle_http($t) == 0, 'external redirect should have a Content-Length: 0'); + $t->{REQUEST} = ( <<EOF GET /redirect/ HTTP/1.0 Host: zzz.example.org |