summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am40
-rw-r--r--src/Makefile.in167
-rw-r--r--src/SConscript7
-rw-r--r--src/array.c17
-rw-r--r--src/array.h1
-rw-r--r--src/base.h16
-rw-r--r--src/chunk.h1
-rw-r--r--src/configfile-glue.c4
-rw-r--r--src/configfile.c3
-rw-r--r--src/connections.c25
-rw-r--r--src/etag.c2
-rw-r--r--src/fdevent.c4
-rw-r--r--src/http_auth.c16
-rw-r--r--src/lemon.c32
-rw-r--r--src/log.c104
-rw-r--r--src/log.h2
-rw-r--r--src/mod_access.c1
-rw-r--r--src/mod_accesslog.c72
-rw-r--r--src/mod_alias.c1
-rw-r--r--src/mod_auth.c27
-rw-r--r--src/mod_cgi.c48
-rw-r--r--src/mod_cml.c3
-rw-r--r--src/mod_cml_funcs.c8
-rw-r--r--src/mod_cml_lua.c2
-rw-r--r--src/mod_compress.c5
-rw-r--r--src/mod_dirlisting.c184
-rw-r--r--src/mod_evasive.c18
-rw-r--r--src/mod_evhost.c21
-rw-r--r--src/mod_expire.c21
-rw-r--r--src/mod_extforward.c99
-rw-r--r--src/mod_fastcgi.c224
-rw-r--r--src/mod_flv_streaming.c1
-rw-r--r--src/mod_indexfile.c1
-rw-r--r--src/mod_magnet.c53
-rw-r--r--src/mod_magnet_cache.c4
-rw-r--r--src/mod_mysql_vhost.c2
-rw-r--r--src/mod_proxy.c45
-rw-r--r--src/mod_redirect.c1
-rw-r--r--src/mod_rewrite.c7
-rw-r--r--src/mod_rrdtool.c87
-rw-r--r--src/mod_scgi.c50
-rw-r--r--src/mod_secure_download.c3
-rw-r--r--src/mod_setenv.c1
-rw-r--r--src/mod_simple_vhost.c1
-rw-r--r--src/mod_ssi.c62
-rw-r--r--src/mod_ssi.h1
-rw-r--r--src/mod_staticfile.c1
-rw-r--r--src/mod_status.c4
-rw-r--r--src/mod_trigger_b4_dl.c1
-rw-r--r--src/mod_userdir.c1
-rw-r--r--src/mod_usertrack.c2
-rw-r--r--src/mod_webdav.c5
-rw-r--r--src/network.c21
-rw-r--r--src/request.c30
-rw-r--r--src/response.c14
-rw-r--r--src/server.c32
-rw-r--r--src/settings.h1
-rw-r--r--src/spawn-fcgi.c481
-rw-r--r--src/splaytree.c6
-rw-r--r--src/stat_cache.c42
-rw-r--r--src/version.h12
61 files changed, 996 insertions, 1151 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 1008b36..cb5543c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2,21 +2,41 @@ AM_CFLAGS = $(FAM_CFLAGS)
noinst_PROGRAMS=proc_open lemon # simple-fcgi #graphic evalo bench ajp ssl error_test adserver gen-license
sbin_PROGRAMS=lighttpd lighttpd-angel
-bin_PROGRAMS=spawn-fcgi
LEMON=$(top_builddir)/src/lemon$(EXEEXT)
lemon_SOURCES=lemon.c
lighttpd_angel_SOURCES=lighttpd-angel.c
-#simple_fcgi_SOURCES=simple-fcgi.c
-#simple_fcgi_LDADD=-lfcgi
+.PHONY: versionstamp parsers
+
+versionstamp:
+ @test -f versionstamp.h || touch versionstamp.h; \
+ REVISION=""; \
+ if test -x "`which svnversion`"; then \
+ REVISION="$$(LANG=C svnversion "$(top_srcdir)" 2>/dev/null || echo exported)"; \
+ if test "$$REVISION" = "exported"; then \
+ REVISION=""; \
+ fi; \
+ fi; \
+ if test -z "$$REVISION" -a -x "`which git`"; then \
+ REVISION="$$(cd "$(top_srcdir)"; LANG=C git describe --always 2>/dev/null || echo)"; \
+ fi; \
+ if test -n "$$REVISION"; then \
+ echo "#define REPO_VERSION \"-devel-$$REVISION\"" > versionstamp.h.tmp; \
+ else \
+ echo "#define REPO_VERSION \"\"" > versionstamp.h.tmp; \
+ fi; \
+ if ! diff versionstamp.h.tmp versionstamp.h >/dev/null 2>/dev/null; then \
+ mv versionstamp.h.tmp versionstamp.h; \
+ else \
+ rm versionstamp.h.tmp; \
+ fi
if CROSS_COMPILING
configparser.c configparser.h:
mod_ssi_exprparser.c mod_ssi_exprparser.h:
-.PHONY: parsers
parsers:
else
configparser.h: configparser.c
@@ -29,12 +49,12 @@ mod_ssi_exprparser.c: $(srcdir)/mod_ssi_exprparser.y $(srcdir)/lempar.c lemon$(E
rm -f mod_ssi_exprparser.h
$(LEMON) -q $(srcdir)/mod_ssi_exprparser.y $(srcdir)/lempar.c
-.PHONY: parsers
parsers: configparser.c mod_ssi_exprparser.c
endif
-BUILT_SOURCES = parsers
+BUILT_SOURCES = parsers versionstamp
MAINTAINERCLEANFILES = configparser.c configparser.h mod_ssi_exprparser.c mod_ssi_exprparser.h
+CLEANFILES = versionstamp.h versionstamp.h.tmp
common_src=buffer.c log.c \
keyvalue.c chunk.c \
@@ -58,8 +78,6 @@ common_src=buffer.c log.c \
src = server.c response.c connections.c network.c \
configfile.c configparser.c request.c proc_open.c
-spawn_fcgi_SOURCES=spawn-fcgi.c
-
lib_LTLIBRARIES =
if NO_RDYNAMIC
@@ -259,9 +277,10 @@ hdr = server.h buffer.h network.h log.h keyvalue.h \
configparser.h mod_ssi_exprparser.h \
sys-mmap.h sys-socket.h mod_cml.h mod_cml_funcs.h \
splaytree.h proc_open.h status_counter.h \
- mod_magnet_cache.h
+ mod_magnet_cache.h \
+ version.h
-DEFS= @DEFS@ -DLIBRARY_DIR="\"$(libdir)\"" -DSBIN_DIR="\"$(sbindir)\""
+DEFS= @DEFS@ -DHAVE_VERSION_H -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)
@@ -287,3 +306,4 @@ proc_open_CPPFLAGS= -DDEBUG_PROC_OPEN
noinst_HEADERS = $(hdr)
EXTRA_DIST = mod_skeleton.c configparser.y mod_ssi_exprparser.y lempar.c SConscript
+
diff --git a/src/Makefile.in b/src/Makefile.in
index 7105aa9..701e76e 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -37,7 +37,6 @@ host_triplet = @host@
target_triplet = @target@
noinst_PROGRAMS = proc_open$(EXEEXT) lemon$(EXEEXT)
sbin_PROGRAMS = lighttpd$(EXEEXT) lighttpd-angel$(EXEEXT)
-bin_PROGRAMS = spawn-fcgi$(EXEEXT)
# if the linker doesn't allow referencing symbols of the binary
# we have to put everything into a shared-lib and link it into
@@ -48,7 +47,7 @@ subdir = src
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
@@ -60,8 +59,7 @@ am__vpath_adj = case $$p in \
*) f=$$p;; \
esac;
am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
-am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
- "$(DESTDIR)$(sbindir)"
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(sbindir)"
libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
am__DEPENDENCIES_1 =
@@ -321,9 +319,8 @@ mod_webdav_la_OBJECTS = $(am_mod_webdav_la_OBJECTS)
mod_webdav_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(mod_webdav_la_CFLAGS) \
$(CFLAGS) $(mod_webdav_la_LDFLAGS) $(LDFLAGS) -o $@
-binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
-PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) $(sbin_PROGRAMS)
+PROGRAMS = $(noinst_PROGRAMS) $(sbin_PROGRAMS)
am_lemon_OBJECTS = lemon.$(OBJEXT)
lemon_OBJECTS = $(am_lemon_OBJECTS)
lemon_LDADD = $(LDADD)
@@ -380,9 +377,6 @@ am_proc_open_OBJECTS = proc_open-proc_open.$(OBJEXT) \
proc_open-buffer.$(OBJEXT)
proc_open_OBJECTS = $(am_proc_open_OBJECTS)
proc_open_LDADD = $(LDADD)
-am_spawn_fcgi_OBJECTS = spawn-fcgi.$(OBJEXT)
-spawn_fcgi_OBJECTS = $(am_spawn_fcgi_OBJECTS)
-spawn_fcgi_LDADD = $(LDADD)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@@ -412,8 +406,7 @@ 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) \
- $(lighttpd_angel_SOURCES) $(proc_open_SOURCES) \
- $(spawn_fcgi_SOURCES)
+ $(lighttpd_angel_SOURCES) $(proc_open_SOURCES)
DIST_SOURCES = $(am__liblightcomp_la_SOURCES_DIST) \
$(mod_access_la_SOURCES) $(mod_accesslog_la_SOURCES) \
$(mod_alias_la_SOURCES) $(mod_auth_la_SOURCES) \
@@ -432,8 +425,7 @@ 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) \
- $(lighttpd_angel_SOURCES) $(proc_open_SOURCES) \
- $(spawn_fcgi_SOURCES)
+ $(lighttpd_angel_SOURCES) $(proc_open_SOURCES)
HEADERS = $(noinst_HEADERS)
ETAGS = etags
CTAGS = ctags
@@ -453,25 +445,20 @@ CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CRYPT_LIB = @CRYPT_LIB@
-CXX = @CXX@
-CXXCPP = @CXXCPP@
-CXXDEPMODE = @CXXDEPMODE@
-CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@ -DLIBRARY_DIR="\"$(libdir)\"" -DSBIN_DIR="\"$(sbindir)\""
+DEFS = @DEFS@ -DHAVE_VERSION_H -DLIBRARY_DIR="\"$(libdir)\"" -DSBIN_DIR="\"$(sbindir)\""
DEPDIR = @DEPDIR@
DL_LIB = @DL_LIB@
DSYMUTIL = @DSYMUTIL@
-ECHO = @ECHO@
+DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
-F77 = @F77@
FAM_CFLAGS = @FAM_CFLAGS@
FAM_LIBS = @FAM_LIBS@
-FFLAGS = @FFLAGS@
+FGREP = @FGREP@
GDBM_LIB = @GDBM_LIB@
GREP = @GREP@
INSTALL = @INSTALL@
@@ -480,24 +467,29 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LBER_LIB = @LBER_LIB@
+LD = @LD@
LDAP_LIB = @LDAP_LIB@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LUA_CFLAGS = @LUA_CFLAGS@
LUA_LIBS = @LUA_LIBS@
-MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MEMCACHE_LIB = @MEMCACHE_LIB@
MKDIR_P = @MKDIR_P@
MYSQL_CONFIG = @MYSQL_CONFIG@
MYSQL_INCLUDE = @MYSQL_INCLUDE@
MYSQL_LIBS = @MYSQL_LIBS@
+NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
@@ -528,8 +520,7 @@ abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
-ac_ct_CXX = @ac_ct_CXX@
-ac_ct_F77 = @ac_ct_F77@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
@@ -560,6 +551,7 @@ libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
@@ -576,14 +568,16 @@ target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AM_CFLAGS = $(FAM_CFLAGS)
LEMON = $(top_builddir)/src/lemon$(EXEEXT)
lemon_SOURCES = lemon.c
lighttpd_angel_SOURCES = lighttpd-angel.c
-BUILT_SOURCES = parsers
+BUILT_SOURCES = parsers versionstamp
MAINTAINERCLEANFILES = configparser.c configparser.h mod_ssi_exprparser.c mod_ssi_exprparser.h
+CLEANFILES = versionstamp.h versionstamp.h.tmp
common_src = buffer.c log.c \
keyvalue.c chunk.c \
http_chunk.c stream.c fdevent.c \
@@ -605,7 +599,6 @@ common_src = buffer.c log.c \
src = server.c response.c connections.c network.c configfile.c \
configparser.c request.c proc_open.c $(am__append_2)
-spawn_fcgi_SOURCES = spawn-fcgi.c
#lib_LTLIBRARIES += mod_httptls.la
#mod_httptls_la_SOURCES = mod_httptls.c
@@ -738,7 +731,8 @@ hdr = server.h buffer.h network.h log.h keyvalue.h \
configparser.h mod_ssi_exprparser.h \
sys-mmap.h sys-socket.h mod_cml.h mod_cml_funcs.h \
splaytree.h proc_open.h status_counter.h \
- mod_magnet_cache.h
+ mod_magnet_cache.h \
+ version.h
lighttpd_SOURCES = $(src)
lighttpd_LDADD = $(PCRE_LIB) $(DL_LIB) $(SENDFILE_LIB) $(ATTR_LIB) $(common_libadd) $(SSL_LIB) $(FAM_LIBS)
@@ -766,12 +760,12 @@ all: $(BUILT_SOURCES)
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -791,9 +785,9 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
@@ -888,34 +882,6 @@ mod_usertrack.la: $(mod_usertrack_la_OBJECTS) $(mod_usertrack_la_DEPENDENCIES)
$(mod_usertrack_la_LINK) -rpath $(libdir) $(mod_usertrack_la_OBJECTS) $(mod_usertrack_la_LIBADD) $(LIBS)
mod_webdav.la: $(mod_webdav_la_OBJECTS) $(mod_webdav_la_DEPENDENCIES)
$(mod_webdav_la_LINK) -rpath $(libdir) $(mod_webdav_la_OBJECTS) $(mod_webdav_la_LIBADD) $(LIBS)
-install-binPROGRAMS: $(bin_PROGRAMS)
- @$(NORMAL_INSTALL)
- test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
- @list='$(bin_PROGRAMS)'; for p in $$list; do \
- p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
- if test -f $$p \
- || test -f $$p1 \
- ; then \
- f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
- echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
- $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
- else :; fi; \
- done
-
-uninstall-binPROGRAMS:
- @$(NORMAL_UNINSTALL)
- @list='$(bin_PROGRAMS)'; for p in $$list; do \
- f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
- echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
- rm -f "$(DESTDIR)$(bindir)/$$f"; \
- done
-
-clean-binPROGRAMS:
- @list='$(bin_PROGRAMS)'; for p in $$list; do \
- f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
- echo " rm -f $$p $$f"; \
- rm -f $$p $$f ; \
- done
clean-noinstPROGRAMS:
@list='$(noinst_PROGRAMS)'; for p in $$list; do \
@@ -963,9 +929,6 @@ lighttpd-angel$(EXEEXT): $(lighttpd_angel_OBJECTS) $(lighttpd_angel_DEPENDENCIES
proc_open$(EXEEXT): $(proc_open_OBJECTS) $(proc_open_DEPENDENCIES)
@rm -f proc_open$(EXEEXT)
$(LINK) $(proc_open_OBJECTS) $(proc_open_LDADD) $(LIBS)
-spawn-fcgi$(EXEEXT): $(spawn_fcgi_OBJECTS) $(spawn_fcgi_DEPENDENCIES)
- @rm -f spawn-fcgi$(EXEEXT)
- $(LINK) $(spawn_fcgi_OBJECTS) $(spawn_fcgi_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -1098,7 +1061,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/request.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/response.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spawn-fcgi.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splaytree.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stat_cache.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/status_counter.Po@am__quote@
@@ -1486,7 +1448,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
@@ -1558,10 +1520,8 @@ check-am: all-am
check: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) check-am
all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS)
-install-binPROGRAMS: install-libLTLIBRARIES
-
installdirs:
- for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)"; do \
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(sbindir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: $(BUILT_SOURCES)
@@ -1582,6 +1542,7 @@ install-strip:
mostlyclean-generic:
clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
@@ -1593,9 +1554,8 @@ maintainer-clean-generic:
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
clean: clean-am
-clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
- clean-libtool clean-noinstPROGRAMS clean-sbinPROGRAMS \
- mostlyclean-am
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+ clean-noinstPROGRAMS clean-sbinPROGRAMS mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
@@ -1617,8 +1577,7 @@ install-data-am:
install-dvi: install-dvi-am
-install-exec-am: install-binPROGRAMS install-libLTLIBRARIES \
- install-sbinPROGRAMS
+install-exec-am: install-libLTLIBRARIES install-sbinPROGRAMS
install-html: install-html-am
@@ -1650,36 +1609,55 @@ ps: ps-am
ps-am:
-uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES \
- uninstall-sbinPROGRAMS
+uninstall-am: uninstall-libLTLIBRARIES uninstall-sbinPROGRAMS
.MAKE: install-am install-strip
-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
- clean-generic clean-libLTLIBRARIES clean-libtool \
- clean-noinstPROGRAMS clean-sbinPROGRAMS ctags distclean \
- distclean-compile distclean-generic distclean-libtool \
- distclean-tags distdir dvi dvi-am html html-am info info-am \
- install install-am install-binPROGRAMS install-data \
- install-data-am install-dvi install-dvi-am install-exec \
- install-exec-am install-html install-html-am install-info \
- install-info-am install-libLTLIBRARIES install-man install-pdf \
- install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \
- install-strip installcheck installcheck-am installdirs \
- maintainer-clean maintainer-clean-generic mostlyclean \
- mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
- pdf pdf-am ps ps-am tags uninstall uninstall-am \
- uninstall-binPROGRAMS uninstall-libLTLIBRARIES \
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libLTLIBRARIES clean-libtool clean-noinstPROGRAMS \
+ clean-sbinPROGRAMS ctags distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-libLTLIBRARIES \
+ install-man install-pdf install-pdf-am install-ps \
+ install-ps-am install-sbinPROGRAMS install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-libLTLIBRARIES \
uninstall-sbinPROGRAMS
-#simple_fcgi_SOURCES=simple-fcgi.c
-#simple_fcgi_LDADD=-lfcgi
+.PHONY: versionstamp parsers
+
+versionstamp:
+ @test -f versionstamp.h || touch versionstamp.h; \
+ REVISION=""; \
+ if test -x "`which svnversion`"; then \
+ REVISION="$$(LANG=C svnversion "$(top_srcdir)" 2>/dev/null || echo exported)"; \
+ if test "$$REVISION" = "exported"; then \
+ REVISION=""; \
+ fi; \
+ fi; \
+ if test -z "$$REVISION" -a -x "`which git`"; then \
+ REVISION="$$(cd "$(top_srcdir)"; LANG=C git describe --always 2>/dev/null || echo)"; \
+ fi; \
+ if test -n "$$REVISION"; then \
+ echo "#define REPO_VERSION \"-devel-$$REVISION\"" > versionstamp.h.tmp; \
+ else \
+ echo "#define REPO_VERSION \"\"" > versionstamp.h.tmp; \
+ fi; \
+ if ! diff versionstamp.h.tmp versionstamp.h >/dev/null 2>/dev/null; then \
+ mv versionstamp.h.tmp versionstamp.h; \
+ else \
+ rm versionstamp.h.tmp; \
+ fi
@CROSS_COMPILING_TRUE@configparser.c configparser.h:
@CROSS_COMPILING_TRUE@mod_ssi_exprparser.c mod_ssi_exprparser.h:
-@CROSS_COMPILING_TRUE@.PHONY: parsers
@CROSS_COMPILING_TRUE@parsers:
@CROSS_COMPILING_FALSE@configparser.h: configparser.c
@CROSS_COMPILING_FALSE@configparser.c: $(srcdir)/configparser.y $(srcdir)/lempar.c lemon$(EXEEXT)
@@ -1691,7 +1669,6 @@ uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES \
@CROSS_COMPILING_FALSE@ rm -f mod_ssi_exprparser.h
@CROSS_COMPILING_FALSE@ $(LEMON) -q $(srcdir)/mod_ssi_exprparser.y $(srcdir)/lempar.c
-@CROSS_COMPILING_FALSE@.PHONY: parsers
@CROSS_COMPILING_FALSE@parsers: configparser.c mod_ssi_exprparser.c
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/src/SConscript b/src/SConscript
index 21dabf6..40bdb7c 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -70,7 +70,7 @@ modules = {
'mod_cml' : {
'src' : [ 'mod_cml_lua.c', 'mod_cml.c', 'mod_cml_funcs.c' ],
'lib' : [ env['LIBPCRE'], env['LIBMEMCACHE'], env['LIBLUA'], env['LIBLUALIB'] ] },
- 'mod_uploadprogress' : { 'src' : [ 'mod_uploadprogress.c' ] },
+# 'mod_uploadprogress' : { 'src' : [ 'mod_uploadprogress.c' ] },
'mod_evasive' : { 'src' : [ 'mod_evasive.c' ] },
'mod_ssi' : { 'src' : [ 'mod_ssi_exprparser.c', 'mod_ssi_expr.c', 'mod_ssi.c' ], 'lib' : [ env['LIBPCRE'] ] },
'mod_flv_streaming' : { 'src' : [ 'mod_flv_streaming.c' ] },
@@ -153,8 +153,6 @@ else:
instbin = env.Program(bin_targets, src, LINKFLAGS = bin_linkflags, LIBS= [ env['LIBS'], common_lib, env['LIBDL'] ])
env.Depends(instbin, configparser)
-spawn_fcgi = env.Program("spawn-fcgi", "spawn-fcgi.c")
-
if env['COMMON_LIB'] == 'bin':
common_lib = instbin[1]
@@ -168,9 +166,6 @@ for module in modules.keys():
inst = []
-Default(spawn_fcgi)
-inst += env.Install('${bindir}', spawn_fcgi)
-
if env['build_dynamic']:
Default(instbin[0], instlib)
inst += env.Install('${sbindir}', instbin[0])
diff --git a/src/array.c b/src/array.c
index d8751aa..ddcb578 100644
--- a/src/array.c
+++ b/src/array.c
@@ -146,6 +146,23 @@ data_unset *array_get_unused_element(array *a, data_type_t t) {
return ds;
}
+void array_set_key_value(array *hdrs, const char *key, size_t key_len, const char *value, size_t val_len) {
+ data_string *ds_dst;
+
+ if (NULL != (ds_dst = (data_string *)array_get_element(hdrs, key))) {
+ buffer_copy_string_len(ds_dst->value, value, val_len);
+ return;
+ }
+
+ if (NULL == (ds_dst = (data_string *)array_get_unused_element(hdrs, TYPE_STRING))) {
+ ds_dst = data_string_init();
+ }
+
+ buffer_copy_string_len(ds_dst->key, key, key_len);
+ buffer_copy_string_len(ds_dst->value, value, val_len);
+ array_insert_unique(hdrs, (data_unset *)ds_dst);
+}
+
/* replace or insert data, return the old one with the same key */
data_unset *array_replace(array *a, data_unset *du) {
int ndx;
diff --git a/src/array.h b/src/array.h
index 6efaac8..9b23699 100644
--- a/src/array.h
+++ b/src/array.h
@@ -165,6 +165,7 @@ data_unset *array_pop(array *a);
int array_print(array *a, int depth);
data_unset *array_get_unused_element(array *a, data_type_t t);
data_unset *array_get_element(array *a, const char *key);
+void array_set_key_value(array *hdrs, const char *key, size_t key_len, const char *value, size_t val_len);
data_unset *array_replace(array *a, data_unset *du);
int array_strcasecmp(const char *a, size_t a_len, const char *b, size_t b_len);
void array_print_indent(int depth);
diff --git a/src/base.h b/src/base.h
index a111766..bcb2325 100644
--- a/src/base.h
+++ b/src/base.h
@@ -183,11 +183,15 @@ typedef struct {
} response;
typedef struct {
- buffer *scheme;
+ buffer *scheme; /* scheme without colon or slashes ( "http" or "https" ) */
+
+ /* authority with optional portnumber ("site.name" or "site.name:8080" ) NOTE: without "username:password@" */
buffer *authority;
+
+ /* path including leading slash ("/" or "/index.html") - urldecoded, and sanitized ( buffer_path_simplify() && buffer_urldecode_path() ) */
buffer *path;
- buffer *path_raw;
- buffer *query;
+ buffer *path_raw; /* raw path, as sent from client. no urldecoding or path simplifying */
+ buffer *query; /* querystring ( everything after "?", ie: in "/index.php?foo=1", query is "foo=1" ) */
} request_uri;
typedef struct {
@@ -270,6 +274,7 @@ typedef struct {
unsigned short ssl_use_sslv2;
unsigned short use_ipv6;
+ unsigned short defer_accept;
unsigned short is_ssl;
unsigned short allow_http11;
unsigned short etag_use_inode;
@@ -533,7 +538,7 @@ typedef struct server {
/* the errorlog */
int errorlog_fd;
- enum { ERRORLOG_STDERR, ERRORLOG_FILE, ERRORLOG_SYSLOG } errorlog_mode;
+ enum { ERRORLOG_STDERR, ERRORLOG_FILE, ERRORLOG_SYSLOG, ERRORLOG_PIPE } errorlog_mode;
buffer *errorlog_buf;
fdevents *ev, *ev_ins;
@@ -582,6 +587,9 @@ typedef struct server {
time_t last_generated_debug_ts;
time_t startup_ts;
+ char entropy[8]; /* from /dev/[u]random if possible, otherwise rand() */
+ char is_real_entropy; /* whether entropy is from /dev/[u]random */
+
buffer *ts_debug_str;
buffer *ts_date_str;
diff --git a/src/chunk.h b/src/chunk.h
index c3c91ab..e43d3eb 100644
--- a/src/chunk.h
+++ b/src/chunk.h
@@ -3,6 +3,7 @@
#include "buffer.h"
#include "array.h"
+#include "sys-mmap.h"
typedef struct chunk {
enum { UNUSED_CHUNK, MEM_CHUNK, FILE_CHUNK } type;
diff --git a/src/configfile-glue.c b/src/configfile-glue.c
index 774589f..0fa665c 100644
--- a/src/configfile-glue.c
+++ b/src/configfile-glue.c
@@ -49,7 +49,7 @@ int config_insert_values_internal(server *srv, array *ca, const config_values_t
buffer_copy_string_buffer(ds->value, ((data_string *)(da->value->data[j]))->value);
if (!da->is_index_key) {
/* the id's were generated automaticly, as we copy now we might have to renumber them
- * this is used to prepend server.modules by mod_indexfiles as it has to be loaded
+ * this is used to prepend server.modules by mod_indexfile as it has to be loaded
* before mod_fastcgi and friends */
buffer_copy_string_buffer(ds->key, ((data_string *)(da->value->data[j]))->key);
}
@@ -181,7 +181,7 @@ int config_insert_values_global(server *srv, array *ca, const config_values_t cv
return config_insert_values_internal(srv, ca, cv);
}
-unsigned short sock_addr_get_port(sock_addr *addr) {
+static unsigned short sock_addr_get_port(sock_addr *addr) {
#ifdef HAVE_IPV6
return ntohs(addr->plain.sa_family ? addr->ipv6.sin6_port : addr->ipv4.sin_port);
#else
diff --git a/src/configfile.c b/src/configfile.c
index e45db85..11117e7 100644
--- a/src/configfile.c
+++ b/src/configfile.c
@@ -96,6 +96,7 @@ static int config_insert(server *srv) {
{ "etag.use-size", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 51 */
{ "server.reject-expect-100-with-417", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 52 */
{ "debug.log-timeouts", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 53 */
+ { "server.defer-accept", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 54 */
{ "server.host", "use server.bind instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
{ "server.docroot", "use server.document-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
{ "server.virtual-root", "load mod_simple_vhost and use simple-vhost.server-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
@@ -164,6 +165,7 @@ static int config_insert(server *srv) {
s->is_ssl = 0;
s->ssl_use_sslv2 = 0;
s->use_ipv6 = 0;
+ s->defer_accept = 0;
#ifdef HAVE_LSTAT
s->follow_symlink = 1;
#endif
@@ -182,6 +184,7 @@ static int config_insert(server *srv) {
cv[7].destination = s->server_tag;
cv[8].destination = &(s->use_ipv6);
+ cv[54].destination = &(s->defer_accept);
/* 13 max-worker */
diff --git a/src/connections.c b/src/connections.c
index 994c1d2..bddb914 100644
--- a/src/connections.c
+++ b/src/connections.c
@@ -192,7 +192,7 @@ static void dump_packet(const unsigned char *data, size_t len) {
static int connection_handle_read_ssl(server *srv, connection *con) {
#ifdef USE_OPENSSL
- int r, ssl_err, len;
+ int r, ssl_err, len, count = 0;
buffer *b = NULL;
if (!con->conf.is_ssl) return -1;
@@ -221,13 +221,15 @@ static int connection_handle_read_ssl(server *srv, connection *con) {
/* we move the buffer to the chunk-queue, no need to free it */
chunkqueue_append_buffer_weak(con->read_queue, b);
+ count += len;
con->bytes_read += len;
b = NULL;
}
- } while (len > 0);
+ } while (len > 0 && count < MAX_READ_LIMIT);
if (len < 0) {
+ int oerrno = errno;
switch ((r = SSL_get_error(con->ssl, len))) {
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
@@ -257,11 +259,11 @@ static int connection_handle_read_ssl(server *srv, connection *con) {
r, ERR_error_string(ssl_err, NULL));
}
- switch(errno) {
+ switch(oerrno) {
default:
log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL:",
- len, r, errno,
- strerror(errno));
+ len, r, oerrno,
+ strerror(oerrno));
break;
}
@@ -334,6 +336,7 @@ static int connection_handle_read(server *srv, connection *con) {
b = chunkqueue_get_append_buffer(con->read_queue);
buffer_prepare_copy(b, 4 * 1024);
} else {
+ if (toread > MAX_READ_LIMIT) toread = MAX_READ_LIMIT;
b = chunkqueue_get_append_buffer(con->read_queue);
buffer_prepare_copy(b, toread + 1);
}
@@ -858,7 +861,7 @@ int connection_reset(server *srv, connection *con) {
*
* we get called by the state-engine and by the fdevent-handler
*/
-int connection_handle_read_state(server *srv, connection *con) {
+static int connection_handle_read_state(server *srv, connection *con) {
connection_state_t ostate = con->state;
chunk *c, *last_chunk;
off_t last_offset;
@@ -1156,7 +1159,7 @@ int connection_handle_read_state(server *srv, connection *con) {
return 0;
}
-handler_t connection_handle_fdevent(void *s, void *context, int revents) {
+static handler_t connection_handle_fdevent(void *s, void *context, int revents) {
server *srv = (server *)s;
connection *con = context;
@@ -1180,7 +1183,7 @@ handler_t connection_handle_fdevent(void *s, void *context, int revents) {
/* FIXME: revents = 0x19 still means that we should read from the queue */
if (revents & FDEVENT_HUP) {
if (con->state == CON_STATE_CLOSE) {
- con->close_timeout_ts = 0;
+ con->close_timeout_ts = srv->cur_ts - 2;
} else {
/* sigio reports the wrong event here
*
@@ -1249,7 +1252,7 @@ handler_t connection_handle_fdevent(void *s, void *context, int revents) {
} else {
/* nothing to read */
- con->close_timeout_ts = 0;
+ con->close_timeout_ts = srv->cur_ts - 2;
}
}
@@ -1601,10 +1604,10 @@ int connection_state_machine(server *srv, connection *con) {
} else {
/* nothing to read */
- con->close_timeout_ts = 0;
+ con->close_timeout_ts = srv->cur_ts - 2;
}
} else {
- con->close_timeout_ts = 0;
+ con->close_timeout_ts = srv->cur_ts - 2;
}
if (srv->cur_ts - con->close_timeout_ts > 1) {
diff --git a/src/etag.c b/src/etag.c
index 630956f..c44278b 100644
--- a/src/etag.c
+++ b/src/etag.c
@@ -44,7 +44,7 @@ int etag_mutate(buffer *mut, buffer *etag) {
size_t i;
uint32_t h;
- for (h=0, i=0; i < etag->used; ++i) h = (h<<5)^(h>>27)^(etag->ptr[i]);
+ for (h=0, i=0; i < etag->used-1; ++i) h = (h<<5)^(h>>27)^(etag->ptr[i]);
buffer_reset(mut);
buffer_copy_string_len(mut, CONST_STR_LEN("\""));
diff --git a/src/fdevent.c b/src/fdevent.c
index e59e110..92ff0e9 100644
--- a/src/fdevent.c
+++ b/src/fdevent.c
@@ -92,7 +92,7 @@ int fdevent_reset(fdevents *ev) {
return 0;
}
-fdnode *fdnode_init() {
+static fdnode *fdnode_init() {
fdnode *fdn;
fdn = calloc(1, sizeof(*fdn));
@@ -100,7 +100,7 @@ fdnode *fdnode_init() {
return fdn;
}
-void fdnode_free(fdnode *fdn) {
+static void fdnode_free(fdnode *fdn) {
free(fdn);
}
diff --git a/src/http_auth.c b/src/http_auth.c
index ccd087e..ba65713 100644
--- a/src/http_auth.c
+++ b/src/http_auth.c
@@ -728,10 +728,15 @@ static int http_auth_basic_password_compare(server *srv, mod_auth_plugin_data *p
char c = username->ptr[i];
if (!isalpha(c) &&
- !isdigit(c)) {
+ !isdigit(c) &&
+ (c != ' ') &&
+ (c != '@') &&
+ (c != '-') &&
+ (c != '_') &&
+ (c != '.') ) {
log_error_write(srv, __FILE__, __LINE__, "sbd",
- "ldap: invalid character (a-zA-Z0-9 allowed) in username:", username, i);
+ "ldap: invalid character (- _.@a-zA-Z0-9 allowed) in username:", username, i);
return -1;
}
@@ -865,7 +870,11 @@ int http_auth_basic_check(server *srv, connection *con, mod_auth_plugin_data *p,
buffer_free(username);
buffer_free(password);
- log_error_write(srv, __FILE__, __LINE__, "s", "get_password failed");
+ if (AUTH_BACKEND_UNSET == p->conf.auth_backend) {
+ log_error_write(srv, __FILE__, __LINE__, "s", "auth.backend is not set");
+ } else {
+ log_error_write(srv, __FILE__, __LINE__, "s", "get_password failed");
+ }
return 0;
}
@@ -1184,6 +1193,7 @@ int http_auth_digest_generate_nonce(server *srv, mod_auth_plugin_data *p, buffer
/* we assume sizeof(time_t) == 4 here, but if not it ain't a problem at all */
LI_ltostr(hh, srv->cur_ts);
MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
+ MD5_Update(&Md5Ctx, (unsigned char *)srv->entropy, sizeof(srv->entropy));
LI_ltostr(hh, rand());
MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
diff --git a/src/lemon.c b/src/lemon.c
index d4c71ef..ce83ead 100644
--- a/src/lemon.c
+++ b/src/lemon.c
@@ -31,6 +31,7 @@ extern long strtol();
extern void free();
extern int access();
extern int atoi();
+extern char *getenv();
#ifndef __WIN32__
# if defined(_WIN32) || defined(WIN32)
@@ -39,7 +40,7 @@ extern int atoi();
#endif
/* #define PRIVATE static */
-#define PRIVATE
+#define PRIVATE static
#ifdef TEST
#define MAXRHS 5 /* Set low to exercise exception code */
@@ -50,6 +51,8 @@ extern int atoi();
char *msort();
extern void *malloc();
+extern void memory_error();
+
/******** From the file "action.h" *************************************/
struct action *Action_new();
struct action *Action_sort();
@@ -291,7 +294,6 @@ struct lemon {
};
#define MemoryCheck(X) if((X)==0){ \
- extern void memory_error(); \
memory_error(); \
}
@@ -445,14 +447,16 @@ struct acttab {
#define acttab_yylookahead(X,N) ((X)->aAction[N].lookahead)
/* Free all memory associated with the given acttab */
-void acttab_free(acttab *p){
+/*
+PRIVATE void acttab_free(acttab *p){
free( p->aAction );
free( p->aLookahead );
free( p );
}
+*/
/* Allocate a new acttab structure */
-acttab *acttab_alloc(void){
+PRIVATE acttab *acttab_alloc(void){
acttab *p = malloc( sizeof(*p) );
if( p==0 ){
fprintf(stderr,"Unable to allocate memory for a new acttab.");
@@ -464,7 +468,7 @@ acttab *acttab_alloc(void){
/* Add a new action to the current transaction set
*/
-void acttab_action(acttab *p, int lookahead, int action){
+PRIVATE void acttab_action(acttab *p, int lookahead, int action){
if( p->nLookahead>=p->nLookaheadAlloc ){
p->nLookaheadAlloc += 25;
p->aLookahead = realloc( p->aLookahead,
@@ -497,7 +501,7 @@ void acttab_action(acttab *p, int lookahead, int action){
**
** Return the offset into the action table of the new transaction.
*/
-int acttab_insert(acttab *p){
+PRIVATE int acttab_insert(acttab *p){
int i, j, k, n;
assert( p->nLookahead>0 );
@@ -2603,7 +2607,7 @@ struct lemon *lemp;
}
}
-void ConfigPrint(fp,cfp)
+PRIVATE void ConfigPrint(fp,cfp)
FILE *fp;
struct config *cfp;
{
@@ -2640,7 +2644,7 @@ struct lemon *lemp;
}
/* Print a plink chain */
-PRIVATE void PlinkPrint(out,plp,tag)
+void PlinkPrint(out,plp,tag)
FILE *out;
struct plink *plp;
char *tag;
@@ -2657,7 +2661,7 @@ char *tag;
/* Print an action to the given file descriptor. Return FALSE if
** nothing was actually printed.
*/
-int PrintAction(struct action *ap, FILE *fp, int indent){
+PRIVATE int PrintAction(struct action *ap, FILE *fp, int indent){
int result = 1;
switch( ap->type ){
case SHIFT:
@@ -2731,6 +2735,7 @@ struct lemon *lemp;
return;
}
+ extern int access();
/* Search for the file "name" which is in the same directory as
** the exacutable */
PRIVATE char *pathsearch(argv0,name,modemask)
@@ -2741,7 +2746,6 @@ int modemask;
char *pathlist;
char *path,*cp;
char c;
- extern int access();
#ifdef __WIN32__
cp = strrchr(argv0,'\\');
@@ -2755,7 +2759,6 @@ int modemask;
if( path ) sprintf(path,"%s/%s",argv0,name);
*cp = c;
}else{
- extern char *getenv();
pathlist = getenv("PATH");
if( pathlist==0 ) pathlist = ".:/bin:/usr/bin";
path = (char *)malloc( strlen(pathlist)+strlen(name)+2 );
@@ -2894,7 +2897,7 @@ int *lineno;
** The following routine emits code for the destructor for the
** symbol sp
*/
-void emit_destructor_code(out,sp,lemp,lineno)
+PRIVATE void emit_destructor_code(out,sp,lemp,lineno)
FILE *out;
struct symbol *sp;
struct lemon *lemp;
@@ -2932,7 +2935,7 @@ int *lineno;
/*
** Return TRUE (non-zero) if the given symbol has a destructor.
*/
-int has_destructor(sp, lemp)
+PRIVATE int has_destructor(sp, lemp)
struct symbol *sp;
struct lemon *lemp;
{
@@ -3033,7 +3036,7 @@ int *lineno;
** union, also set the ".dtnum" field of every terminal and nonterminal
** symbol.
*/
-void print_stack_union(out,lemp,plineno,mhflag)
+PRIVATE void print_stack_union(out,lemp,plineno,mhflag)
FILE *out; /* The output stream */
struct lemon *lemp; /* The main info structure for this parser */
int *plineno; /* Pointer to the line number */
@@ -3684,7 +3687,6 @@ char *SetNew(){
int i;
s = (char*)malloc( global_size );
if( s==0 ){
- extern void memory_error();
memory_error();
}
for(i=0; i<global_size; i++) s[i] = 0;
diff --git a/src/log.c b/src/log.c
index 8195a5f..e65532d 100644
--- a/src/log.c
+++ b/src/log.c
@@ -54,13 +54,96 @@ int openDevNull(int fd) {
return (tmpfd != -1) ? 0 : -1;
}
+int open_logfile_or_pipe(server *srv, const char* logfile) {
+ int fd;
+
+ if (logfile[0] == '|') {
+#ifdef HAVE_FORK
+ /* create write pipe and spawn process */
+
+ int to_log_fds[2];
+ pid_t pid;
+
+ if (pipe(to_log_fds)) {
+ log_error_write(srv, __FILE__, __LINE__, "ss", "pipe failed: ", strerror(errno));
+ return -1;
+ }
+
+ /* fork, execve */
+ switch (pid = fork()) {
+ case 0:
+ /* child */
+ close(STDIN_FILENO);
+
+ /* dup the filehandle to STDIN */
+ if (to_log_fds[0] != STDIN_FILENO) {
+ if (STDIN_FILENO != dup2(to_log_fds[0], STDIN_FILENO)) {
+ log_error_write(srv, __FILE__, __LINE__, "ss",
+ "dup2 failed: ", strerror(errno));
+ exit(-1);
+ }
+ close(to_log_fds[0]);
+ }
+ close(to_log_fds[1]);
+
+#ifndef FD_CLOEXEC
+ {
+ int i;
+ /* we don't need the client socket */
+ for (i = 3; i < 256; i++) {
+ close(i);
+ }
+ }
+#endif
+
+ /* close old stderr */
+ openDevNull(STDERR_FILENO);
+
+ /* exec the log-process (skip the | ) */
+ execl("/bin/sh", "sh", "-c", logfile + 1, NULL);
+ log_error_write(srv, __FILE__, __LINE__, "sss",
+ "spawning log process failed: ", strerror(errno),
+ logfile + 1);
+
+ exit(-1);
+ break;
+ case -1:
+ /* error */
+ log_error_write(srv, __FILE__, __LINE__, "ss", "fork failed: ", strerror(errno));
+ return -1;
+ default:
+ close(to_log_fds[0]);
+ fd = to_log_fds[1];
+ break;
+ }
+
+#else
+ return -1;
+#endif
+ } else if (-1 == (fd = open(logfile, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
+ log_error_write(srv, __FILE__, __LINE__, "SSSS",
+ "opening errorlog '", logfile,
+ "' failed: ", strerror(errno));
+
+ return -1;
+ }
+
+#ifdef FD_CLOEXEC
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
+#endif
+
+ return fd;
+}
+
+
/**
* open the errorlog
*
- * we have 3 possibilities:
+ * we have 4 possibilities:
* - stderr (default)
* - syslog
* - logfile
+ * - pipe
*
* if the open failed, report to the user and die
*
@@ -80,18 +163,10 @@ int log_error_open(server *srv) {
} else if (!buffer_is_empty(srv->srvconf.errorlog_file)) {
const char *logfile = srv->srvconf.errorlog_file->ptr;
- if (-1 == (srv->errorlog_fd = open(logfile, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
- log_error_write(srv, __FILE__, __LINE__, "SSSS",
- "opening errorlog '", logfile,
- "' failed: ", strerror(errno));
-
+ if (-1 == (srv->errorlog_fd = open_logfile_or_pipe(srv, logfile))) {
return -1;
}
-#ifdef FD_CLOEXEC
- /* close fd on exec (cgi) */
- fcntl(srv->errorlog_fd, F_SETFD, FD_CLOEXEC);
-#endif
- srv->errorlog_mode = ERRORLOG_FILE;
+ srv->errorlog_mode = (logfile[0] == '|') ? ERRORLOG_PIPE : ERRORLOG_FILE;
}
log_error_write(srv, __FILE__, __LINE__, "s", "server started");
@@ -122,7 +197,7 @@ int log_error_open(server *srv) {
*/
int log_error_cycle(server *srv) {
- /* only cycle if we are not in syslog-mode */
+ /* only cycle if the error log is a file */
if (srv->errorlog_mode == ERRORLOG_FILE) {
const char *logfile = srv->srvconf.errorlog_file->ptr;
@@ -130,7 +205,7 @@ int log_error_cycle(server *srv) {
int new_fd;
- if (-1 == (new_fd = open(logfile, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
+ if (-1 == (new_fd = open_logfile_or_pipe(srv, logfile))) {
/* write to old log */
log_error_write(srv, __FILE__, __LINE__, "SSSSS",
"cycling errorlog '", logfile,
@@ -158,6 +233,7 @@ int log_error_cycle(server *srv) {
int log_error_close(server *srv) {
switch(srv->errorlog_mode) {
+ case ERRORLOG_PIPE:
case ERRORLOG_FILE:
close(srv->errorlog_fd);
break;
@@ -177,6 +253,7 @@ int log_error_write(server *srv, const char *filename, unsigned int line, const
va_list ap;
switch(srv->errorlog_mode) {
+ case ERRORLOG_PIPE:
case ERRORLOG_FILE:
case ERRORLOG_STDERR:
/* cache the generated timestamp */
@@ -270,6 +347,7 @@ int log_error_write(server *srv, const char *filename, unsigned int line, const
va_end(ap);
switch(srv->errorlog_mode) {
+ case ERRORLOG_PIPE:
case ERRORLOG_FILE:
buffer_append_string_len(srv->errorlog_buf, CONST_STR_LEN("\n"));
write(srv->errorlog_fd, srv->errorlog_buf->ptr, srv->errorlog_buf->used - 1);
diff --git a/src/log.h b/src/log.h
index bdd7af4..583288b 100644
--- a/src/log.h
+++ b/src/log.h
@@ -10,6 +10,8 @@ int openDevNull(int fd);
#define WP() log_error_write(srv, __FILE__, __LINE__, "");
+int open_logfile_or_pipe(server *srv, const char* logfile);
+
int log_error_open(server *srv);
int log_error_close(server *srv);
int log_error_write(server *srv, const char *filename, unsigned int line, const char *fmt, ...);
diff --git a/src/mod_access.c b/src/mod_access.c
index 67b6802..12b4d97 100644
--- a/src/mod_access.c
+++ b/src/mod_access.c
@@ -175,6 +175,7 @@ URIHANDLER_FUNC(mod_access_uri_handler) {
}
+int mod_access_plugin_init(plugin *p);
int mod_access_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("access");
diff --git a/src/mod_accesslog.c b/src/mod_accesslog.c
index e5ba553..024f2e9 100644
--- a/src/mod_accesslog.c
+++ b/src/mod_accesslog.c
@@ -156,7 +156,7 @@ INIT_FUNC(mod_accesslog_init) {
return p;
}
-int accesslog_parse_format(server *srv, format_fields *fields, buffer *format) {
+static int accesslog_parse_format(server *srv, format_fields *fields, buffer *format) {
size_t i, j, k = 0, start = 0;
if (format->used == 0) return -1;
@@ -475,74 +475,9 @@ SETDEFAULTS_FUNC(log_access_open) {
if (s->access_logfile->used < 2) continue;
- if (s->access_logfile->ptr[0] == '|') {
-#ifdef HAVE_FORK
- /* create write pipe and spawn process */
-
- int to_log_fds[2];
- pid_t pid;
-
- if (pipe(to_log_fds)) {
- log_error_write(srv, __FILE__, __LINE__, "ss", "pipe failed: ", strerror(errno));
- return HANDLER_ERROR;
- }
-
- /* fork, execve */
- switch (pid = fork()) {
- case 0:
- /* child */
-
- close(STDIN_FILENO);
- dup2(to_log_fds[0], STDIN_FILENO);
- close(to_log_fds[0]);
- /* not needed */
- close(to_log_fds[1]);
-
- openDevNull(STDERR_FILENO);
-
- /* we don't need the client socket */
- for (i = 3; i < 256; i++) {
- close(i);
- }
-
- /* exec the log-process (skip the | )
- *
- */
-
- execl("/bin/sh", "sh", "-c", s->access_logfile->ptr + 1, (char *)NULL);
-
- log_error_write(srv, __FILE__, __LINE__, "sss",
- "spawning log-process failed: ", strerror(errno),
- s->access_logfile->ptr + 1);
-
- exit(-1);
- break;
- case -1:
- /* error */
- log_error_write(srv, __FILE__, __LINE__, "ss", "fork failed: ", strerror(errno));
- break;
- default:
- close(to_log_fds[0]);
-
- s->log_access_fd = to_log_fds[1];
-
- break;
- }
-#else
- return -1;
-#endif
- } else if (-1 == (s->log_access_fd =
- open(s->access_logfile->ptr, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) {
-
- log_error_write(srv, __FILE__, __LINE__, "ssb",
- "opening access-log failed:",
- strerror(errno), s->access_logfile);
-
+ if (-1 == (s->log_access_fd = open_logfile_or_pipe(srv, s->access_logfile->ptr)))
return HANDLER_ERROR;
- }
-#ifdef FD_CLOEXEC
- fcntl(s->log_access_fd, F_SETFD, FD_CLOEXEC);
-#endif
+
}
return HANDLER_GO_ON;
@@ -876,6 +811,7 @@ REQUESTDONE_FUNC(log_access_write) {
}
+int mod_accesslog_plugin_init(plugin *p);
int mod_accesslog_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("accesslog");
diff --git a/src/mod_alias.c b/src/mod_alias.c
index 8a54547..933338d 100644
--- a/src/mod_alias.c
+++ b/src/mod_alias.c
@@ -187,6 +187,7 @@ PHYSICALPATH_FUNC(mod_alias_physical_handler) {
/* this function is called at dlopen() time and inits the callbacks */
+int mod_alias_plugin_init(plugin *p);
int mod_alias_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("alias");
diff --git a/src/mod_auth.c b/src/mod_auth.c
index 77d30f2..e508c00 100644
--- a/src/mod_auth.c
+++ b/src/mod_auth.c
@@ -313,20 +313,20 @@ SETDEFAULTS_FUNC(mod_auth_set_defaults) {
config_values_t cv[] = {
{ "auth.backend", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
- { "auth.backend.plain.groupfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
- { "auth.backend.plain.userfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
- { "auth.require", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION },
- { "auth.backend.ldap.hostname", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
- { "auth.backend.ldap.base-dn", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
- { "auth.backend.ldap.filter", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
- { "auth.backend.ldap.ca-file", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
- { "auth.backend.ldap.starttls", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },
- { "auth.backend.ldap.bind-dn", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
+ { "auth.backend.plain.groupfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
+ { "auth.backend.plain.userfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
+ { "auth.require", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 3 */
+ { "auth.backend.ldap.hostname", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 4 */
+ { "auth.backend.ldap.base-dn", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 5 */
+ { "auth.backend.ldap.filter", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 6 */
+ { "auth.backend.ldap.ca-file", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 7 */
+ { "auth.backend.ldap.starttls", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 8 */
+ { "auth.backend.ldap.bind-dn", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 9 */
{ "auth.backend.ldap.bind-pw", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 10 */
- { "auth.backend.ldap.allow-empty-pw", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION },
- { "auth.backend.htdigest.userfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
- { "auth.backend.htpasswd.userfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },
- { "auth.debug", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 13 */
+ { "auth.backend.ldap.allow-empty-pw", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 11 */
+ { "auth.backend.htdigest.userfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 12 */
+ { "auth.backend.htpasswd.userfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 13 */
+ { "auth.debug", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 14 */
{ NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
};
@@ -614,6 +614,7 @@ handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s) {
#endif
}
+int mod_auth_plugin_init(plugin *p);
int mod_auth_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("auth");
diff --git a/src/mod_cgi.c b/src/mod_cgi.c
index 3b032f1..fa5e111 100644
--- a/src/mod_cgi.c
+++ b/src/mod_cgi.c
@@ -24,6 +24,7 @@
#include <fcntl.h>
#include "server.h"
+#include "stat_cache.h"
#include "keyvalue.h"
#include "log.h"
#include "connections.h"
@@ -36,6 +37,8 @@
# include <sys/filio.h>
#endif
+#include "version.h"
+
enum {EOL_UNSET, EOL_N, EOL_RN};
typedef struct {
@@ -696,11 +699,11 @@ static int cgi_env_add(char_array *env, const char *key, size_t key_len, const c
if (!key || !val) return -1;
- dst = malloc(key_len + val_len + 3);
+ dst = malloc(key_len + val_len + 2);
memcpy(dst, key, key_len);
dst[key_len] = '=';
- /* add the \0 from the value */
- memcpy(dst + key_len + 1, val, val_len + 1);
+ memcpy(dst + key_len + 1, val, val_len);
+ dst[key_len + 1 + val_len] = '\0';
if (env->size == 0) {
env->size = 16;
@@ -776,25 +779,23 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
/* not needed */
close(to_cgi_fds[1]);
- /* HACK:
- * this is not nice, but it works
- *
- * we feed the stderr of the CGI to our errorlog, if possible
- */
- if (srv->errorlog_mode == ERRORLOG_FILE) {
- close(STDERR_FILENO);
- dup2(srv->errorlog_fd, STDERR_FILENO);
- }
-
/* create environment */
env.ptr = NULL;
env.size = 0;
env.used = 0;
- cgi_env_add(&env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_NAME"/"PACKAGE_VERSION));
+ if (buffer_is_empty(con->conf.server_tag)) {
+ cgi_env_add(&env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_DESC));
+ } else {
+ cgi_env_add(&env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_BUF_LEN(con->conf.server_tag));
+ }
if (!buffer_is_empty(con->server_name)) {
- cgi_env_add(&env, CONST_STR_LEN("SERVER_NAME"), CONST_BUF_LEN(con->server_name));
+ size_t len = con->server_name->used - 1;
+ char *colon = strchr(con->server_name->ptr, ':');
+ if (colon) len = colon - con->server_name->ptr;
+
+ cgi_env_add(&env, CONST_STR_LEN("SERVER_NAME"), con->server_name->ptr, len);
} else {
#ifdef HAVE_IPV6
s = inet_ntop(srv_sock->addr.plain.sa_family,
@@ -972,9 +973,15 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
buffer_prepare_append(p->tmp_buf, ds->key->used + 2);
for (j = 0; j < ds->key->used - 1; j++) {
- p->tmp_buf->ptr[p->tmp_buf->used++] =
- light_isalnum((unsigned char)ds->key->ptr[j]) ?
- toupper((unsigned char)ds->key->ptr[j]) : '_';
+ char cr = '_';
+ if (light_isalpha(ds->key->ptr[j])) {
+ /* upper-case */
+ cr = ds->key->ptr[j] & ~32;
+ } else if (light_isdigit(ds->key->ptr[j])) {
+ /* copy */
+ cr = ds->key->ptr[j];
+ }
+ p->tmp_buf->ptr[p->tmp_buf->used++] = cr;
}
p->tmp_buf->ptr[p->tmp_buf->used++] = '\0';
@@ -1203,6 +1210,7 @@ URIHANDLER_FUNC(cgi_is_handled) {
size_t k, s_len;
plugin_data *p = p_d;
buffer *fn = con->physical.path;
+ stat_cache_entry *sce = NULL;
if (con->mode != DIRECT) return HANDLER_GO_ON;
@@ -1210,6 +1218,9 @@ URIHANDLER_FUNC(cgi_is_handled) {
mod_cgi_patch_connection(srv, con, p);
+ if (HANDLER_ERROR == stat_cache_get_entry(srv, con, con->physical.path, &sce)) return HANDLER_GO_ON;
+ if (!S_ISREG(sce->st.st_mode)) return HANDLER_GO_ON;
+
s_len = fn->used - 1;
for (k = 0; k < p->conf.cgi->used; k++) {
@@ -1369,6 +1380,7 @@ SUBREQUEST_FUNC(mod_cgi_handle_subrequest) {
}
+int mod_cgi_plugin_init(plugin *p);
int mod_cgi_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("cgi");
diff --git a/src/mod_cml.c b/src/mod_cml.c
index 2221368..03e264c 100644
--- a/src/mod_cml.c
+++ b/src/mod_cml.c
@@ -178,7 +178,7 @@ static int mod_cml_patch_connection(server *srv, connection *con, plugin_data *p
}
#undef PATCH
-int cache_call_lua(server *srv, connection *con, plugin_data *p, buffer *cml_file) {
+static int cache_call_lua(server *srv, connection *con, plugin_data *p, buffer *cml_file) {
buffer *b;
char *c;
@@ -305,6 +305,7 @@ URIHANDLER_FUNC(mod_cml_is_handled) {
}
}
+int mod_cml_plugin_init(plugin *p);
int mod_cml_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("cache");
diff --git a/src/mod_cml_funcs.c b/src/mod_cml_funcs.c
index 07c7673..82bca10 100644
--- a/src/mod_cml_funcs.c
+++ b/src/mod_cml_funcs.c
@@ -93,7 +93,7 @@ int f_file_mtime(lua_State *L) {
return 1;
}
-int f_dir_files_iter(lua_State *L) {
+static int f_dir_files_iter(lua_State *L) {
DIR *d;
struct dirent *de;
@@ -211,7 +211,7 @@ int f_memcache_exists(lua_State *L) {
}
if (NULL == (r = mc_aget(mc,
- lua_tostring(L, 1), lua_strlen(L, 1)))) {
+ (char*) lua_tostring(L, 1), lua_strlen(L, 1)))) {
lua_pushboolean(L, 0);
return 1;
@@ -248,7 +248,7 @@ int f_memcache_get_string(lua_State *L) {
}
if (NULL == (r = mc_aget(mc,
- lua_tostring(L, 1), lua_strlen(L, 1)))) {
+ (char*) lua_tostring(L, 1), lua_strlen(L, 1)))) {
lua_pushnil(L);
return 1;
}
@@ -285,7 +285,7 @@ int f_memcache_get_long(lua_State *L) {
}
if (NULL == (r = mc_aget(mc,
- lua_tostring(L, 1), lua_strlen(L, 1)))) {
+ (char*) lua_tostring(L, 1), lua_strlen(L, 1)))) {
lua_pushnil(L);
return 1;
}
diff --git a/src/mod_cml_lua.c b/src/mod_cml_lua.c
index 08df0c9..ae25ef1 100644
--- a/src/mod_cml_lua.c
+++ b/src/mod_cml_lua.c
@@ -105,7 +105,7 @@ static int c_to_lua_push(lua_State *L, int tbl, const char *key, size_t key_len,
}
-int cache_export_get_params(lua_State *L, int tbl, buffer *qrystr) {
+static int cache_export_get_params(lua_State *L, int tbl, buffer *qrystr) {
size_t is_key = 1;
size_t i;
char *key = NULL, *val = NULL;
diff --git a/src/mod_compress.c b/src/mod_compress.c
index 2127ad3..4b33983 100644
--- a/src/mod_compress.c
+++ b/src/mod_compress.c
@@ -104,7 +104,7 @@ FREE_FUNC(mod_compress_free) {
}
/* 0 on success, -1 for error */
-int mkdir_recursive(char *dir) {
+static int mkdir_recursive(char *dir) {
char *p = dir;
if (!dir || !dir[0])
@@ -126,7 +126,7 @@ int mkdir_recursive(char *dir) {
}
/* 0 on success, -1 for error */
-int mkdir_for_file(char *filename) {
+static int mkdir_for_file(char *filename) {
char *p = filename;
if (!filename || !filename[0])
@@ -815,6 +815,7 @@ PHYSICALPATH_FUNC(mod_compress_physical) {
return HANDLER_GO_ON;
}
+int mod_compress_plugin_init(plugin *p);
int mod_compress_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("compress");
diff --git a/src/mod_dirlisting.c b/src/mod_dirlisting.c
index 511003f..71b6df9 100644
--- a/src/mod_dirlisting.c
+++ b/src/mod_dirlisting.c
@@ -31,6 +31,8 @@
#include <attr/attributes.h>
#endif
+#include "version.h"
+
/* plugin config for all request/connections */
typedef struct {
@@ -52,8 +54,11 @@ typedef struct {
unsigned short hide_dot_files;
unsigned short show_readme;
unsigned short hide_readme_file;
+ unsigned short encode_readme;
unsigned short show_header;
unsigned short hide_header_file;
+ unsigned short encode_header;
+ unsigned short auto_layout;
excludes_buffer *excludes;
@@ -73,7 +78,7 @@ typedef struct {
plugin_config conf;
} plugin_data;
-excludes_buffer *excludes_buffer_init(void) {
+static excludes_buffer *excludes_buffer_init(void) {
excludes_buffer *exb;
exb = calloc(1, sizeof(*exb));
@@ -81,7 +86,7 @@ excludes_buffer *excludes_buffer_init(void) {
return exb;
}
-int excludes_buffer_append(excludes_buffer *exb, buffer *string) {
+static int excludes_buffer_append(excludes_buffer *exb, buffer *string) {
#ifdef HAVE_PCRE_H
size_t i;
const char *errptr;
@@ -128,7 +133,7 @@ int excludes_buffer_append(excludes_buffer *exb, buffer *string) {
#endif
}
-void excludes_buffer_free(excludes_buffer *exb) {
+static void excludes_buffer_free(excludes_buffer *exb) {
#ifdef HAVE_PCRE_H
size_t i;
@@ -243,6 +248,9 @@ static int parse_config_entry(server *srv, plugin_config *s, array *ca, const ch
#define CONFIG_HIDE_HEADER_FILE "dir-listing.hide-header-file"
#define CONFIG_DIR_LISTING "server.dir-listing"
#define CONFIG_SET_FOOTER "dir-listing.set-footer"
+#define CONFIG_ENCODE_README "dir-listing.encode-readme"
+#define CONFIG_ENCODE_HEADER "dir-listing.encode-header"
+#define CONFIG_AUTO_LAYOUT "dir-listing.auto-layout"
SETDEFAULTS_FUNC(mod_dirlisting_set_defaults) {
@@ -260,7 +268,10 @@ SETDEFAULTS_FUNC(mod_dirlisting_set_defaults) {
{ CONFIG_SHOW_HEADER, NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 7 */
{ CONFIG_HIDE_HEADER_FILE, NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 8 */
{ CONFIG_DIR_LISTING, NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 9 */
- { CONFIG_SET_FOOTER, NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 10 */
+ { CONFIG_SET_FOOTER, NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 10 */
+ { CONFIG_ENCODE_README, NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 11 */
+ { CONFIG_ENCODE_HEADER, NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 12 */
+ { CONFIG_AUTO_LAYOUT, NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 13 */
{ NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
};
@@ -282,6 +293,10 @@ SETDEFAULTS_FUNC(mod_dirlisting_set_defaults) {
s->hide_readme_file = 0;
s->show_header = 0;
s->hide_header_file = 0;
+ s->encode_readme = 1;
+ s->encode_header = 1;
+ s->auto_layout = 1;
+
s->encoding = buffer_init();
s->set_footer = buffer_init();
@@ -296,6 +311,9 @@ SETDEFAULTS_FUNC(mod_dirlisting_set_defaults) {
cv[8].destination = &(s->hide_header_file);
cv[9].destination = &(s->dir_listing); /* old name */
cv[10].destination = s->set_footer;
+ cv[11].destination = &(s->encode_readme);
+ cv[12].destination = &(s->encode_header);
+ cv[13].destination = &(s->auto_layout);
p->config_storage[i] = s;
ca = ((data_config *)srv->config_context->data[i])->value;
@@ -326,6 +344,9 @@ static int mod_dirlisting_patch_connection(server *srv, connection *con, plugin_
PATCH(hide_header_file);
PATCH(excludes);
PATCH(set_footer);
+ PATCH(encode_readme);
+ PATCH(encode_header);
+ PATCH(auto_layout);
/* skip the first, the global context */
for (i = 1; i < srv->config_context->used; i++) {
@@ -360,6 +381,12 @@ static int mod_dirlisting_patch_connection(server *srv, connection *con, plugin_
PATCH(set_footer);
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN(CONFIG_EXCLUDE))) {
PATCH(excludes);
+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN(CONFIG_ENCODE_README))) {
+ PATCH(encode_readme);
+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN(CONFIG_ENCODE_HEADER))) {
+ PATCH(encode_header);
+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN(CONFIG_AUTO_LAYOUT))) {
+ PATCH(auto_layout);
}
}
}
@@ -454,56 +481,58 @@ static int http_list_directory_sizefmt(char *buf, off_t size) {
static void http_list_directory_header(server *srv, connection *con, plugin_data *p, buffer *out) {
UNUSED(srv);
- buffer_append_string_len(out, CONST_STR_LEN(
- "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n"
- "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n"
- "<head>\n"
- "<title>Index of "
- ));
- buffer_append_string_encoded(out, CONST_BUF_LEN(con->uri.path), ENCODING_MINIMAL_XML);
- buffer_append_string_len(out, CONST_STR_LEN("</title>\n"));
-
- if (p->conf.external_css->used > 1) {
- buffer_append_string_len(out, CONST_STR_LEN("<link rel=\"stylesheet\" type=\"text/css\" href=\""));
- buffer_append_string_buffer(out, p->conf.external_css);
- buffer_append_string_len(out, CONST_STR_LEN("\" />\n"));
- } else {
+ if (p->conf.auto_layout) {
buffer_append_string_len(out, CONST_STR_LEN(
- "<style type=\"text/css\">\n"
- "a, a:active {text-decoration: none; color: blue;}\n"
- "a:visited {color: #48468F;}\n"
- "a:hover, a:focus {text-decoration: underline; color: red;}\n"
- "body {background-color: #F5F5F5;}\n"
- "h2 {margin-bottom: 12px;}\n"
- "table {margin-left: 12px;}\n"
- "th, td {"
- " font: 90% monospace;"
- " text-align: left;"
- "}\n"
- "th {"
- " font-weight: bold;"
- " padding-right: 14px;"
- " padding-bottom: 3px;"
- "}\n"
- "td {padding-right: 14px;}\n"
- "td.s, th.s {text-align: right;}\n"
- "div.list {"
- " background-color: white;"
- " border-top: 1px solid #646464;"
- " border-bottom: 1px solid #646464;"
- " padding-top: 10px;"
- " padding-bottom: 14px;"
- "}\n"
- "div.foot {"
- " font: 90% monospace;"
- " color: #787878;"
- " padding-top: 4px;"
- "}\n"
- "</style>\n"
+ "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n"
+ "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n"
+ "<head>\n"
+ "<title>Index of "
));
- }
+ buffer_append_string_encoded(out, CONST_BUF_LEN(con->uri.path), ENCODING_MINIMAL_XML);
+ buffer_append_string_len(out, CONST_STR_LEN("</title>\n"));
+
+ if (p->conf.external_css->used > 1) {
+ buffer_append_string_len(out, CONST_STR_LEN("<link rel=\"stylesheet\" type=\"text/css\" href=\""));
+ buffer_append_string_buffer(out, p->conf.external_css);
+ buffer_append_string_len(out, CONST_STR_LEN("\" />\n"));
+ } else {
+ buffer_append_string_len(out, CONST_STR_LEN(
+ "<style type=\"text/css\">\n"
+ "a, a:active {text-decoration: none; color: blue;}\n"
+ "a:visited {color: #48468F;}\n"
+ "a:hover, a:focus {text-decoration: underline; color: red;}\n"
+ "body {background-color: #F5F5F5;}\n"
+ "h2 {margin-bottom: 12px;}\n"
+ "table {margin-left: 12px;}\n"
+ "th, td {"
+ " font: 90% monospace;"
+ " text-align: left;"
+ "}\n"
+ "th {"
+ " font-weight: bold;"
+ " padding-right: 14px;"
+ " padding-bottom: 3px;"
+ "}\n"
+ "td {padding-right: 14px;}\n"
+ "td.s, th.s {text-align: right;}\n"
+ "div.list {"
+ " background-color: white;"
+ " border-top: 1px solid #646464;"
+ " border-bottom: 1px solid #646464;"
+ " padding-top: 10px;"
+ " padding-bottom: 14px;"
+ "}\n"
+ "div.foot {"
+ " font: 90% monospace;"
+ " color: #787878;"
+ " padding-top: 4px;"
+ "}\n"
+ "</style>\n"
+ ));
+ }
- buffer_append_string_len(out, CONST_STR_LEN("</head>\n<body>\n"));
+ buffer_append_string_len(out, CONST_STR_LEN("</head>\n<body>\n"));
+ }
/* HEADER.txt */
if (p->conf.show_header) {
@@ -515,9 +544,13 @@ static void http_list_directory_header(server *srv, connection *con, plugin_data
buffer_append_string_len(p->tmp_buf, CONST_STR_LEN("HEADER.txt"));
if (-1 != stream_open(&s, p->tmp_buf)) {
- buffer_append_string_len(out, CONST_STR_LEN("<pre class=\"header\">"));
- buffer_append_string_encoded(out, s.start, s.size, ENCODING_MINIMAL_XML);
- buffer_append_string_len(out, CONST_STR_LEN("</pre>"));
+ if (p->conf.encode_header) {
+ buffer_append_string_len(out, CONST_STR_LEN("<pre class=\"header\">"));
+ buffer_append_string_encoded(out, s.start, s.size, ENCODING_MINIMAL_XML);
+ buffer_append_string_len(out, CONST_STR_LEN("</pre>"));
+ } else {
+ buffer_append_string_len(out, s.start, s.size);
+ }
}
stream_close(&s);
}
@@ -564,30 +597,36 @@ static void http_list_directory_footer(server *srv, connection *con, plugin_data
buffer_append_string_len(p->tmp_buf, CONST_STR_LEN("README.txt"));
if (-1 != stream_open(&s, p->tmp_buf)) {
- buffer_append_string_len(out, CONST_STR_LEN("<pre class=\"readme\">"));
- buffer_append_string_encoded(out, s.start, s.size, ENCODING_MINIMAL_XML);
- buffer_append_string_len(out, CONST_STR_LEN("</pre>"));
+ if (p->conf.encode_readme) {
+ buffer_append_string_len(out, CONST_STR_LEN("<pre class=\"readme\">"));
+ buffer_append_string_encoded(out, s.start, s.size, ENCODING_MINIMAL_XML);
+ buffer_append_string_len(out, CONST_STR_LEN("</pre>"));
+ } else {
+ buffer_append_string_len(out, s.start, s.size);
+ }
}
stream_close(&s);
}
- buffer_append_string_len(out, CONST_STR_LEN(
- "<div class=\"foot\">"
- ));
+ if(p->conf.auto_layout) {
+ buffer_append_string_len(out, CONST_STR_LEN(
+ "<div class=\"foot\">"
+ ));
- if (p->conf.set_footer->used > 1) {
- buffer_append_string_buffer(out, p->conf.set_footer);
- } else if (buffer_is_empty(con->conf.server_tag)) {
- buffer_append_string_len(out, CONST_STR_LEN(PACKAGE_NAME "/" PACKAGE_VERSION));
- } else {
- buffer_append_string_buffer(out, con->conf.server_tag);
- }
+ if (p->conf.set_footer->used > 1) {
+ buffer_append_string_buffer(out, p->conf.set_footer);
+ } else if (buffer_is_empty(con->conf.server_tag)) {
+ buffer_append_string_len(out, CONST_STR_LEN(PACKAGE_DESC));
+ } else {
+ buffer_append_string_buffer(out, con->conf.server_tag);
+ }
- buffer_append_string_len(out, CONST_STR_LEN(
- "</div>\n"
- "</body>\n"
- "</html>\n"
- ));
+ buffer_append_string_len(out, CONST_STR_LEN(
+ "</div>\n"
+ "</body>\n"
+ "</html>\n"
+ ));
+ }
}
static int http_list_directory(server *srv, connection *con, plugin_data *p, buffer *dir) {
@@ -904,6 +943,7 @@ URIHANDLER_FUNC(mod_dirlisting_subrequest) {
/* this function is called at dlopen() time and inits the callbacks */
+int mod_dirlisting_plugin_init(plugin *p);
int mod_dirlisting_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("dirlisting");
diff --git a/src/mod_evasive.c b/src/mod_evasive.c
index 2970711..467bada 100644
--- a/src/mod_evasive.c
+++ b/src/mod_evasive.c
@@ -27,6 +27,7 @@
typedef struct {
unsigned short max_conns;
+ unsigned short silent;
} plugin_config;
typedef struct {
@@ -72,7 +73,8 @@ SETDEFAULTS_FUNC(mod_evasive_set_defaults) {
size_t i = 0;
config_values_t cv[] = {
- { "evasive.max-conns-per-ip", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },
+ { "evasive.max-conns-per-ip", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
+ { "evasive.silent", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
{ NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
};
@@ -83,8 +85,10 @@ SETDEFAULTS_FUNC(mod_evasive_set_defaults) {
s = calloc(1, sizeof(plugin_config));
s->max_conns = 0;
+ s->silent = 0;
cv[0].destination = &(s->max_conns);
+ cv[1].destination = &(s->silent);
p->config_storage[i] = s;
@@ -103,6 +107,7 @@ static int mod_evasive_patch_connection(server *srv, connection *con, plugin_dat
plugin_config *s = p->config_storage[0];
PATCH(max_conns);
+ PATCH(silent);
/* skip the first, the global context */
for (i = 1; i < srv->config_context->used; i++) {
@@ -118,6 +123,8 @@ static int mod_evasive_patch_connection(server *srv, connection *con, plugin_dat
if (buffer_is_equal_string(du->key, CONST_STR_LEN("evasive.max-conns-per-ip"))) {
PATCH(max_conns);
+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("evasive.silent"))) {
+ PATCH(silent);
}
}
}
@@ -172,9 +179,11 @@ URIHANDLER_FUNC(mod_evasive_uri_handler) {
conns_by_ip++;
if (conns_by_ip > p->conf.max_conns) {
- log_error_write(srv, __FILE__, __LINE__, "ss",
- inet_ntop_cache_get_ip(srv, &(con->dst_addr)),
- "turned away. Too many connections.");
+ if (!p->conf.silent) {
+ log_error_write(srv, __FILE__, __LINE__, "ss",
+ inet_ntop_cache_get_ip(srv, &(con->dst_addr)),
+ "turned away. Too many connections.");
+ }
con->http_status = 403;
con->mode = DIRECT;
@@ -186,6 +195,7 @@ URIHANDLER_FUNC(mod_evasive_uri_handler) {
}
+int mod_evasive_plugin_init(plugin *p);
int mod_evasive_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("evasive");
diff --git a/src/mod_evhost.c b/src/mod_evhost.c
index 09a90a2..2cb695b 100644
--- a/src/mod_evhost.c
+++ b/src/mod_evhost.c
@@ -115,6 +115,7 @@ SETDEFAULTS_FUNC(mod_evhost_set_defaults) {
* # %2 => domain name without tld
* # %3 => subdomain 1 name
* # %4 => subdomain 2 name
+ * # %_ => fqdn (without port info)
* #
* evhost.path-pattern = "/home/ckruse/dev/www/%3/htdocs/"
*
@@ -154,11 +155,12 @@ SETDEFAULTS_FUNC(mod_evhost_set_defaults) {
}
/**
- * assign the different parts of the domain to array-indezes
- * - %0 - full hostname (authority w/o port)
+ * assign the different parts of the domain to array-indezes (sub2.sub1.domain.tld)
+ * - %0 - domain.tld
* - %1 - tld
- * - %2 - domain.tld
- * - %3 -
+ * - %2 - domain
+ * - %3 - sub1
+ * - ...
*/
static int mod_evhost_parse_host(connection *con,array *host) {
@@ -287,6 +289,16 @@ static handler_t mod_evhost_uri_handler(server *srv, connection *con, void *p_d)
if (*(ptr+1) == '%') {
/* %% */
buffer_append_string_len(p->tmp_buf,CONST_STR_LEN("%"));
+ } else if (*(ptr+1) == '_' ) {
+ /* %_ == full hostname */
+ char *colon = strchr(con->uri.authority->ptr, ':');
+
+ if(colon == NULL) {
+ buffer_append_string_buffer(p->tmp_buf, con->uri.authority); // adds fqdn
+ } else {
+ /* strip the port out of the authority-part of the URI scheme */
+ buffer_append_string_len(p->tmp_buf, con->uri.authority->ptr, colon - con->uri.authority->ptr); // adds fqdn
+ }
} else if (NULL != (ds = (data_string *)array_get_element(parsed_host,p->conf.path_pieces[i]->ptr))) {
if (ds->value->used) {
buffer_append_string_buffer(p->tmp_buf,ds->value);
@@ -318,6 +330,7 @@ static handler_t mod_evhost_uri_handler(server *srv, connection *con, void *p_d)
return HANDLER_GO_ON;
}
+int mod_evhost_plugin_init(plugin *p);
int mod_evhost_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("evhost");
diff --git a/src/mod_expire.c b/src/mod_expire.c
index 6aed514..6c0b924 100644
--- a/src/mod_expire.c
+++ b/src/mod_expire.c
@@ -62,9 +62,9 @@ FREE_FUNC(mod_expire_free) {
size_t i;
for (i = 0; i < srv->config_context->used; i++) {
plugin_config *s = p->config_storage[i];
+ if (!s) continue;
array_free(s->expire_url);
-
free(s);
}
free(p->config_storage);
@@ -75,10 +75,10 @@ FREE_FUNC(mod_expire_free) {
return HANDLER_GO_ON;
}
-static int mod_expire_get_offset(server *srv, plugin_data *p, buffer *expire, int *offset) {
+static int mod_expire_get_offset(server *srv, plugin_data *p, buffer *expire, time_t *offset) {
char *ts;
int type = -1;
- int retts = 0;
+ time_t retts = 0;
UNUSED(p);
@@ -302,8 +302,7 @@ URIHANDLER_FUNC(mod_expire_path_handler) {
if (ds->key->used == 0) continue;
if (0 == strncmp(con->uri.path->ptr, ds->key->ptr, ct_len)) {
- int ts;
- time_t t;
+ time_t ts, expires;
size_t len;
stat_cache_entry *sce = NULL;
@@ -312,25 +311,26 @@ URIHANDLER_FUNC(mod_expire_path_handler) {
switch(mod_expire_get_offset(srv, p, ds->value, &ts)) {
case 0:
/* access */
- t = (ts + srv->cur_ts);
+ expires = (ts + srv->cur_ts);
break;
case 1:
/* modification */
- t = (ts + sce->st.st_mtime);
+ expires = (ts + sce->st.st_mtime);
break;
default:
/* -1 is handled at parse-time */
break;
}
+ /* expires should be at least srv->cur_ts */
+ if (expires < srv->cur_ts) expires = srv->cur_ts;
if (0 == (len = strftime(p->expire_tstmp->ptr, p->expire_tstmp->size - 1,
- "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(t))))) {
+ "%a, %d %b %Y %H:%M:%S GMT", gmtime(&(expires))))) {
/* could not set expire header, out of mem */
return HANDLER_GO_ON;
-
}
p->expire_tstmp->used = len + 1;
@@ -340,7 +340,7 @@ URIHANDLER_FUNC(mod_expire_path_handler) {
/* HTTP/1.1 */
buffer_copy_string_len(p->expire_tstmp, CONST_STR_LEN("max-age="));
- buffer_append_long(p->expire_tstmp, ts);
+ buffer_append_long(p->expire_tstmp, expires - srv->cur_ts); /* as expires >= srv->cur_ts the difference is >= 0 */
response_header_overwrite(srv, con, CONST_STR_LEN("Cache-Control"), CONST_BUF_LEN(p->expire_tstmp));
@@ -354,6 +354,7 @@ URIHANDLER_FUNC(mod_expire_path_handler) {
/* this function is called at dlopen() time and inits the callbacks */
+int mod_expire_plugin_init(plugin *p);
int mod_expire_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("expire");
diff --git a/src/mod_extforward.c b/src/mod_extforward.c
index 0b457d6..aabee12 100644
--- a/src/mod_extforward.c
+++ b/src/mod_extforward.c
@@ -80,6 +80,7 @@
typedef struct {
array *forwarder;
+ array *headers;
} plugin_config;
typedef struct {
@@ -135,6 +136,7 @@ FREE_FUNC(mod_extforward_free) {
if (!s) continue;
array_free(s->forwarder);
+ array_free(s->headers);
free(s);
}
@@ -154,7 +156,8 @@ SETDEFAULTS_FUNC(mod_extforward_set_defaults) {
size_t i = 0;
config_values_t cv[] = {
- { "extforward.forwarder", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
+ { "extforward.forwarder", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
+ { "extforward.headers", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
{ NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
};
@@ -167,8 +170,10 @@ SETDEFAULTS_FUNC(mod_extforward_set_defaults) {
s = calloc(1, sizeof(plugin_config));
s->forwarder = array_init();
+ s->headers = array_init();
cv[0].destination = s->forwarder;
+ cv[1].destination = s->headers;
p->config_storage[i] = s;
@@ -187,6 +192,7 @@ static int mod_extforward_patch_connection(server *srv, connection *con, plugin_
plugin_config *s = p->config_storage[0];
PATCH(forwarder);
+ PATCH(headers);
/* skip the first, the global context */
for (i = 1; i < srv->config_context->used; i++) {
@@ -202,6 +208,8 @@ static int mod_extforward_patch_connection(server *srv, connection *con, plugin_
if (buffer_is_equal_string(du->key, CONST_STR_LEN("extforward.forwarder"))) {
PATCH(forwarder);
+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("extforward.headers"))) {
+ PATCH(headers);
}
}
}
@@ -294,37 +302,37 @@ static const char *last_not_in_array(array *a, plugin_data *p)
return NULL;
}
-struct addrinfo *ipstr_to_sockaddr(const char *host)
-{
- struct addrinfo hints, *res0;
- int result;
+static struct addrinfo *ipstr_to_sockaddr(const char *host) {
+ struct addrinfo hints, *res0;
+ int result;
- memset(&hints, 0, sizeof(hints));
+ memset(&hints, 0, sizeof(hints));
#ifndef AI_NUMERICSERV
-/**
- * quoting $ man getaddrinfo
- *
- * NOTES
- * AI_ADDRCONFIG, AI_ALL, and AI_V4MAPPED are available since glibc 2.3.3.
- * AI_NUMERICSERV is available since glibc 2.3.4.
- */
+ /**
+ * quoting $ man getaddrinfo
+ *
+ * NOTES
+ * AI_ADDRCONFIG, AI_ALL, and AI_V4MAPPED are available since glibc 2.3.3.
+ * AI_NUMERICSERV is available since glibc 2.3.4.
+ */
#define AI_NUMERICSERV 0
#endif
- hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
-
- result = getaddrinfo(host, NULL, &hints, &res0);
- if ( result != 0 )
- {
- fprintf(stderr,"could not resolve hostname %s because %s\n", host,gai_strerror(result));
- if (result == EAI_SYSTEM)
- perror("The system error is ");
- return NULL;
- }
- else
- if (res0==0)
- fprintf(stderr, "Problem in resolving hostname %s: succeeded, but no information returned\n", host);
-
- return res0;
+ hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
+
+ result = getaddrinfo(host, NULL, &hints, &res0);
+
+ if (result != 0) {
+ fprintf(stderr, "could not resolve hostname %s because %s\n", host, gai_strerror(result));
+
+ if (result == EAI_SYSTEM)
+ perror("The system error is ");
+
+ return NULL;
+ } else if (res0 == 0) {
+ fprintf(stderr, "Problem in resolving hostname %s: succeeded, but no information returned\n", host);
+ }
+
+ return res0;
}
@@ -351,16 +359,26 @@ URIHANDLER_FUNC(mod_extforward_uri_handler) {
mod_extforward_patch_connection(srv, con, p);
if (con->conf.log_request_handling) {
- log_error_write(srv, __FILE__, __LINE__, "s",
- "-- mod_extforward_uri_handler called");
+ log_error_write(srv, __FILE__, __LINE__, "s",
+ "-- mod_extforward_uri_handler called");
}
- if ((NULL == (forwarded = (data_string *) array_get_element(con->request.headers,"X-Forwarded-For")) &&
- NULL == (forwarded = (data_string *) array_get_element(con->request.headers, "Forwarded-For")))) {
+ if (p->conf.headers->used) {
+ data_string *ds;
+ size_t k;
+
+ for(k = 0; k < p->conf.headers->used; k++) {
+ ds = (data_string *) p->conf.headers->data[k];
+ if (NULL != (forwarded = (data_string*) array_get_element(con->request.headers, ds->value->ptr))) break;
+ }
+ } else {
+ forwarded = (data_string *) array_get_element(con->request.headers,"X-Forwarded-For");
+ if (NULL == forwarded) forwarded = (data_string *) array_get_element(con->request.headers, "Forwarded-For");
+ }
+ if (NULL == forwarded) {
if (con->conf.log_request_handling) {
- log_error_write(srv, __FILE__, __LINE__, "s",
- "no X-Forwarded-For|Forwarded-For: found, skipping");
+ log_error_write(srv, __FILE__, __LINE__, "s", "no forward header found, skipping");
}
return HANDLER_GO_ON;
@@ -368,11 +386,10 @@ URIHANDLER_FUNC(mod_extforward_uri_handler) {
#ifdef HAVE_IPV6
dst_addr_str = inet_ntop(con->dst_addr.plain.sa_family,
- con->dst_addr.plain.sa_family == AF_INET6 ?
- (struct sockaddr *)&(con->dst_addr.ipv6.sin6_addr) :
- (struct sockaddr *)&(con->dst_addr.ipv4.sin_addr),
- b2,
- (sizeof b2) - 1);
+ con->dst_addr.plain.sa_family == AF_INET6 ?
+ (struct sockaddr *)&(con->dst_addr.ipv6.sin6_addr) :
+ (struct sockaddr *)&(con->dst_addr.ipv4.sin_addr),
+ b2, (sizeof b2) - 1);
#else
dst_addr_str = inet_ntoa(con->dst_addr.ipv4.sin_addr);
#endif
@@ -420,6 +437,7 @@ URIHANDLER_FUNC(mod_extforward_uri_handler) {
}
}
#else
+ UNUSED(addrs_left);
sock.ipv4.sin_addr.s_addr = inet_addr(real_remote_addr);
sock.plain.sa_family = (sock.ipv4.sin_addr.s_addr == 0xFFFFFFFF) ? AF_UNSPEC : AF_INET;
#endif
@@ -439,7 +457,7 @@ URIHANDLER_FUNC(mod_extforward_uri_handler) {
buffer_copy_string(con->dst_addr_buf, real_remote_addr);
if (con->conf.log_request_handling) {
- log_error_write(srv, __FILE__, __LINE__, "ss",
+ log_error_write(srv, __FILE__, __LINE__, "ss",
"patching con->dst_addr_buf for the accesslog:", real_remote_addr);
}
/* Now, clean the conf_cond cache, because we may have changed the results of tests */
@@ -479,6 +497,7 @@ CONNECTION_FUNC(mod_extforward_restore) {
/* this function is called at dlopen() time and inits the callbacks */
+int mod_extforward_plugin_init(plugin *p);
int mod_extforward_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("extforward");
diff --git a/src/mod_fastcgi.c b/src/mod_fastcgi.c
index 2f4b03c..0fbfebf 100644
--- a/src/mod_fastcgi.c
+++ b/src/mod_fastcgi.c
@@ -49,6 +49,8 @@
#include <sys/wait.h>
#endif
+#include "version.h"
+
#define FCGI_ENV_ADD_CHECK(ret, con) \
if (ret == -1) { \
con->http_status = 400; \
@@ -316,12 +318,6 @@ typedef struct {
} plugin_config;
typedef struct {
- size_t *ptr;
- size_t used;
- size_t size;
-} buffer_uint;
-
-typedef struct {
char **ptr;
size_t size;
@@ -331,7 +327,6 @@ typedef struct {
/* generic plugin data, shared between all connections */
typedef struct {
PLUGIN_DATA;
- buffer_uint fcgi_request_id;
buffer *fcgi_env;
@@ -389,18 +384,63 @@ typedef struct {
/* ok, we need a prototype */
static handler_t fcgi_handle_fdevent(void *s, void *ctx, int revents);
-int fastcgi_status_copy_procname(buffer *b, fcgi_extension_host *host, fcgi_proc *proc) {
+static void fastcgi_status_copy_procname(buffer *b, fcgi_extension_host *host, fcgi_proc *proc) {
buffer_copy_string_len(b, CONST_STR_LEN("fastcgi.backend."));
buffer_append_string_buffer(b, host->id);
if (proc) {
buffer_append_string_len(b, CONST_STR_LEN("."));
buffer_append_long(b, proc->id);
}
+}
- return 0;
+static void fcgi_proc_load_inc(server *srv, handler_ctx *hctx) {
+ plugin_data *p = hctx->plugin_data;
+ hctx->proc->load++;
+
+ status_counter_inc(srv, CONST_STR_LEN("fastcgi.active-requests"));
+
+ fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
+ buffer_append_string_len(p->statuskey, CONST_STR_LEN(".load"));
+
+ status_counter_set(srv, CONST_BUF_LEN(p->statuskey), hctx->proc->load);
+}
+
+static void fcgi_proc_load_dec(server *srv, handler_ctx *hctx) {
+ plugin_data *p = hctx->plugin_data;
+ hctx->proc->load--;
+
+ status_counter_dec(srv, CONST_STR_LEN("fastcgi.active-requests"));
+
+ fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
+ buffer_append_string_len(p->statuskey, CONST_STR_LEN(".load"));
+
+ status_counter_set(srv, CONST_BUF_LEN(p->statuskey), hctx->proc->load);
+}
+
+static void fcgi_host_assign(server *srv, handler_ctx *hctx, fcgi_extension_host *host) {
+ plugin_data *p = hctx->plugin_data;
+ hctx->host = host;
+ hctx->host->load++;
+
+ fastcgi_status_copy_procname(p->statuskey, hctx->host, NULL);
+ buffer_append_string_len(p->statuskey, CONST_STR_LEN(".load"));
+
+ status_counter_set(srv, CONST_BUF_LEN(p->statuskey), hctx->host->load);
}
-int fastcgi_status_init(server *srv, buffer *b, fcgi_extension_host *host, fcgi_proc *proc) {
+static void fcgi_host_reset(server *srv, handler_ctx *hctx) {
+ plugin_data *p = hctx->plugin_data;
+ hctx->host->load--;
+
+ fastcgi_status_copy_procname(p->statuskey, hctx->host, NULL);
+ buffer_append_string_len(p->statuskey, CONST_STR_LEN(".load"));
+
+ status_counter_set(srv, CONST_BUF_LEN(p->statuskey), hctx->host->load);
+
+ hctx->host = NULL;
+}
+
+static int fastcgi_status_init(server *srv, buffer *b, fcgi_extension_host *host, fcgi_proc *proc) {
#define CLEAN(x) \
fastcgi_status_copy_procname(b, host, proc); \
buffer_append_string_len(b, CONST_STR_LEN(x)); \
@@ -451,10 +491,9 @@ static handler_ctx * handler_ctx_init() {
return hctx;
}
-static void handler_ctx_free(handler_ctx *hctx) {
+static void handler_ctx_free(server *srv, handler_ctx *hctx) {
if (hctx->host) {
- hctx->host->load--;
- hctx->host = NULL;
+ fcgi_host_reset(srv, hctx);
}
buffer_free(hctx->response_header);
@@ -465,7 +504,7 @@ static void handler_ctx_free(handler_ctx *hctx) {
free(hctx);
}
-fcgi_proc *fastcgi_process_init() {
+static fcgi_proc *fastcgi_process_init() {
fcgi_proc *f;
f = calloc(1, sizeof(*f));
@@ -478,7 +517,7 @@ fcgi_proc *fastcgi_process_init() {
return f;
}
-void fastcgi_process_free(fcgi_proc *f) {
+static void fastcgi_process_free(fcgi_proc *f) {
if (!f) return;
fastcgi_process_free(f->next);
@@ -489,7 +528,7 @@ void fastcgi_process_free(fcgi_proc *f) {
free(f);
}
-fcgi_extension_host *fastcgi_host_init() {
+static fcgi_extension_host *fastcgi_host_init() {
fcgi_extension_host *f;
f = calloc(1, sizeof(*f));
@@ -506,7 +545,7 @@ fcgi_extension_host *fastcgi_host_init() {
return f;
}
-void fastcgi_host_free(fcgi_extension_host *h) {
+static void fastcgi_host_free(fcgi_extension_host *h) {
if (!h) return;
buffer_free(h->id);
@@ -525,7 +564,7 @@ void fastcgi_host_free(fcgi_extension_host *h) {
}
-fcgi_exts *fastcgi_extensions_init() {
+static fcgi_exts *fastcgi_extensions_init() {
fcgi_exts *f;
f = calloc(1, sizeof(*f));
@@ -533,7 +572,7 @@ fcgi_exts *fastcgi_extensions_init() {
return f;
}
-void fastcgi_extensions_free(fcgi_exts *f) {
+static void fastcgi_extensions_free(fcgi_exts *f) {
size_t i;
if (!f) return;
@@ -563,7 +602,7 @@ void fastcgi_extensions_free(fcgi_exts *f) {
free(f);
}
-int fastcgi_extension_insert(fcgi_exts *ext, buffer *key, fcgi_extension_host *fh) {
+static int fastcgi_extension_insert(fcgi_exts *ext, buffer *key, fcgi_extension_host *fh) {
fcgi_extension *fe;
size_t i;
@@ -633,12 +672,9 @@ INIT_FUNC(mod_fastcgi_init) {
FREE_FUNC(mod_fastcgi_free) {
plugin_data *p = p_d;
- buffer_uint *r = &(p->fcgi_request_id);
UNUSED(srv);
- if (r->ptr) free(r->ptr);
-
buffer_free(p->fcgi_env);
buffer_free(p->path);
buffer_free(p->parse_response);
@@ -710,8 +746,8 @@ static int env_add(char_array *env, const char *key, size_t key_len, const char
dst = malloc(key_len + val_len + 3);
memcpy(dst, key, key_len);
dst[key_len] = '=';
- /* add the \0 from the value */
- memcpy(dst + key_len + 1, val, val_len + 1);
+ memcpy(dst + key_len + 1, val, val_len);
+ dst[key_len + 1 + val_len] = '\0';
for (i = 0; i < env->used; i++) {
if (0 == strncmp(dst, env->ptr[i], key_len + 1)) {
@@ -1056,10 +1092,7 @@ static int fcgi_spawn_connection(server *srv,
"child exited with status",
WEXITSTATUS(status), host->bin_path);
log_error_write(srv, __FILE__, __LINE__, "s",
- "If you're trying to run PHP as a FastCGI backend, make sure you're using the FastCGI-enabled version.\n"
- "You can find out if it is the right one by executing 'php -v' and it should display '(cgi-fcgi)' "
- "in the output, NOT '(cgi)' NOR '(cli)'.\n"
- "For more information, check http://trac.lighttpd.net/trac/wiki/Docs%3AModFastCGI#preparing-php-as-a-fastcgi-program"
+ "If you're trying to run your app as a FastCGI backend, make sure you're using the FastCGI-enabled version.\n"
"If this is PHP on Gentoo, add 'fastcgi' to the USE flags.");
} else if (WIFSIGNALED(status)) {
log_error_write(srv, __FILE__, __LINE__, "sd",
@@ -1434,52 +1467,7 @@ static int fcgi_set_state(server *srv, handler_ctx *hctx, fcgi_connection_state_
}
-static size_t fcgi_requestid_new(server *srv, plugin_data *p) {
- size_t m = 0;
- size_t i;
- buffer_uint *r = &(p->fcgi_request_id);
-
- UNUSED(srv);
-
- for (i = 0; i < r->used; i++) {
- if (r->ptr[i] > m) m = r->ptr[i];
- }
-
- if (r->size == 0) {
- r->size = 16;
- r->ptr = malloc(sizeof(*r->ptr) * r->size);
- } else if (r->used == r->size) {
- r->size += 16;
- r->ptr = realloc(r->ptr, sizeof(*r->ptr) * r->size);
- }
-
- r->ptr[r->used++] = ++m;
-
- return m;
-}
-
-static int fcgi_requestid_del(server *srv, plugin_data *p, size_t request_id) {
- size_t i;
- buffer_uint *r = &(p->fcgi_request_id);
-
- UNUSED(srv);
-
- for (i = 0; i < r->used; i++) {
- if (r->ptr[i] == request_id) break;
- }
-
- if (i != r->used) {
- /* found */
-
- if (i != r->used - 1) {
- r->ptr[i] = r->ptr[r->used - 1];
- }
- r->used--;
- }
-
- return 0;
-}
-void fcgi_connection_close(server *srv, handler_ctx *hctx) {
+static void fcgi_connection_close(server *srv, handler_ctx *hctx) {
plugin_data *p;
connection *con;
@@ -1495,21 +1483,10 @@ void fcgi_connection_close(server *srv, handler_ctx *hctx) {
srv->cur_fds--;
}
- if (hctx->request_id != 0) {
- fcgi_requestid_del(srv, p, hctx->request_id);
- }
-
if (hctx->host && hctx->proc) {
if (hctx->got_proc) {
/* after the connect the process gets a load */
- hctx->proc->load--;
-
- status_counter_dec(srv, CONST_STR_LEN("fastcgi.active-requests"));
-
- fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
- buffer_append_string_len(p->statuskey, CONST_STR_LEN(".load"));
-
- status_counter_set(srv, CONST_BUF_LEN(p->statuskey), hctx->proc->load);
+ fcgi_proc_load_dec(srv, hctx);
if (p->conf.debug) {
log_error_write(srv, __FILE__, __LINE__, "ssdsbsd",
@@ -1522,7 +1499,7 @@ void fcgi_connection_close(server *srv, handler_ctx *hctx) {
}
- handler_ctx_free(hctx);
+ handler_ctx_free(srv, hctx);
con->plugin_ctx[p->id] = NULL;
}
@@ -1556,8 +1533,6 @@ static int fcgi_reconnect(server *srv, handler_ctx *hctx) {
hctx->fd = -1;
}
- fcgi_requestid_del(srv, p, hctx->request_id);
-
fcgi_set_state(srv, hctx, FCGI_STATE_INIT);
hctx->request_id = 0;
@@ -1576,12 +1551,11 @@ static int fcgi_reconnect(server *srv, handler_ctx *hctx) {
}
if (hctx->proc && hctx->got_proc) {
- hctx->proc->load--;
+ fcgi_proc_load_dec(srv, hctx);
}
/* perhaps another host gives us more luck */
- hctx->host->load--;
- hctx->host = NULL;
+ fcgi_host_reset(srv, hctx);
return 0;
}
@@ -1885,10 +1859,18 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
buffer_prepare_copy(p->fcgi_env, 1024);
- FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_NAME"/"PACKAGE_VERSION)),con)
+ if (buffer_is_empty(con->conf.server_tag)) {
+ FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_DESC)),con)
+ } else {
+ FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_BUF_LEN(con->conf.server_tag)),con)
+ }
if (con->server_name->used) {
- FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_NAME"), CONST_BUF_LEN(con->server_name)),con)
+ size_t len = con->server_name->used - 1;
+ char *colon = strchr(con->server_name->ptr, ':');
+ if (colon) len = colon - con->server_name->ptr;
+
+ FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SERVER_NAME"), con->server_name->ptr, len),con)
} else {
#ifdef HAVE_IPV6
s = inet_ntop(srv_sock->addr.plain.sa_family,
@@ -2060,7 +2042,7 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REQUEST_URI"),
con->request.orig_uri->ptr + (host->strip_request_uri->used - 2),
- con->request.orig_uri->used - (host->strip_request_uri->used - 2));
+ con->request.orig_uri->used - (host->strip_request_uri->used - 2) - 1);
} else {
FCGI_ENV_ADD_CHECK(fcgi_env_add(p->fcgi_env, CONST_STR_LEN("REQUEST_URI"), CONST_BUF_LEN(con->request.orig_uri)),con)
}
@@ -2361,10 +2343,15 @@ static int fastcgi_get_packet(server *srv, handler_ctx *hctx, fastcgi_response_p
/* get at least the FastCGI header */
for (c = hctx->rb->first; c; c = c->next) {
+ size_t weWant = sizeof(*header) - (packet->b->used - 1);
+ size_t weHave = c->mem->used - c->offset - 1;
+
+ if (weHave > weWant) weHave = weWant;
+
if (packet->b->used == 0) {
- buffer_copy_string_len(packet->b, c->mem->ptr + c->offset, c->mem->used - c->offset - 1);
+ buffer_copy_string_len(packet->b, c->mem->ptr + c->offset, weHave);
} else {
- buffer_append_string_len(packet->b, c->mem->ptr + c->offset, c->mem->used - c->offset - 1);
+ buffer_append_string_len(packet->b, c->mem->ptr + c->offset, weHave);
}
if (packet->b->used >= sizeof(*header) + 1) break;
@@ -2577,7 +2564,7 @@ static int fcgi_demux_response(server *srv, handler_ctx *hctx) {
joblist_append(srv, con);
buffer_copy_string_len(dcls->key, "Content-Length", sizeof("Content-Length")-1);
- buffer_copy_long(dcls->value, sce->st.st_size);
+ buffer_copy_off_t(dcls->value, sce->st.st_size);
dcls = (data_string*) array_replace(con->response.headers, (data_unset *)dcls);
if (dcls) dcls->free((data_unset*)dcls);
@@ -2977,30 +2964,17 @@ static handler_t fcgi_write_request(server *srv, handler_ctx *hctx) {
case FCGI_STATE_PREPARE_WRITE:
/* ok, we have the connection */
- hctx->proc->load++;
+ fcgi_proc_load_inc(srv, hctx);
hctx->proc->last_used = srv->cur_ts;
hctx->got_proc = 1;
status_counter_inc(srv, CONST_STR_LEN("fastcgi.requests"));
- status_counter_inc(srv, CONST_STR_LEN("fastcgi.active-requests"));
fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
buffer_append_string_len(p->statuskey, CONST_STR_LEN(".connected"));
status_counter_inc(srv, CONST_BUF_LEN(p->statuskey));
- /* the proc-load */
- fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
- buffer_append_string_len(p->statuskey, CONST_STR_LEN(".load"));
-
- status_counter_set(srv, CONST_BUF_LEN(p->statuskey), hctx->proc->load);
-
- /* the host-load */
- fastcgi_status_copy_procname(p->statuskey, hctx->host, NULL);
- buffer_append_string_len(p->statuskey, CONST_STR_LEN(".load"));
-
- status_counter_set(srv, CONST_BUF_LEN(p->statuskey), hctx->host->load);
-
if (p->conf.debug) {
log_error_write(srv, __FILE__, __LINE__, "ssdsbsd",
"got proc:",
@@ -3011,7 +2985,7 @@ static handler_t fcgi_write_request(server *srv, handler_ctx *hctx) {
/* move the proc-list entry down the list */
if (hctx->request_id == 0) {
- hctx->request_id = fcgi_requestid_new(srv, p);
+ hctx->request_id = 1; /* always use id 1 as we don't use multiplexing */
} else {
log_error_write(srv, __FILE__, __LINE__, "sd",
"fcgi-request is already in use:", hctx->request_id);
@@ -3157,12 +3131,11 @@ SUBREQUEST_FUNC(mod_fastcgi_handle_subrequest) {
*/
/* init handler-context */
- hctx->host = host;
/* we put a connection on this host, move the other new connections to other hosts
*
* as soon as hctx->host is unassigned, decrease the load again */
- hctx->host->load++;
+ fcgi_host_assign(srv, hctx, host);
hctx->proc = NULL;
} else {
host = hctx->host;
@@ -3391,14 +3364,10 @@ static handler_t fcgi_handle_fdevent(void *s, void *ctx, int revents) {
* even if the FCGI_FIN packet is not received yet
*/
} else {
- log_error_write(srv, __FILE__, __LINE__, "sbSBSDSd",
+ log_error_write(srv, __FILE__, __LINE__, "sbsbsd",
"error: unexpected close of fastcgi connection for",
con->uri.path,
- "(no fastcgi process on host:",
- host->host,
- ", port: ",
- host->port,
- " ?)",
+ "(no fastcgi process on socket:", proc->connection_name, "?)",
hctx->state);
connection_set_state(srv, con, CON_STATE_ERROR);
@@ -3639,7 +3608,11 @@ static handler_t fcgi_check_extension(server *srv, connection *con, void *p_d, i
*/
/* the rewrite is only done for /prefix/? matches */
- if (extension->key->ptr[0] == '/' &&
+ if (host->fix_root_path_name && extension->key->ptr[0] == '/' && extension->key->ptr[1] == '\0') {
+ buffer_copy_string(con->request.pathinfo, con->uri.path->ptr);
+ con->uri.path->used = 1;
+ con->uri.path->ptr[con->uri.path->used - 1] = '\0';
+ } else if (extension->key->ptr[0] == '/' &&
con->uri.path->used > extension->key->used &&
NULL != (pathinfo = strchr(con->uri.path->ptr + extension->key->used - 1, '/'))) {
/* rewrite uri.path and pathinfo */
@@ -3648,10 +3621,6 @@ static handler_t fcgi_check_extension(server *srv, connection *con, void *p_d, i
con->uri.path->used -= con->request.pathinfo->used - 1;
con->uri.path->ptr[con->uri.path->used - 1] = '\0';
- } else if (host->fix_root_path_name && extension->key->ptr[0] == '/' && extension->key->ptr[1] == '\0') {
- buffer_copy_string(con->request.pathinfo, con->uri.path->ptr);
- con->uri.path->used = 1;
- con->uri.path->ptr[con->uri.path->used - 1] = '\0';
}
}
}
@@ -3916,6 +3885,7 @@ TRIGGER_FUNC(mod_fastcgi_handle_trigger) {
}
+int mod_fastcgi_plugin_init(plugin *p);
int mod_fastcgi_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("fastcgi");
diff --git a/src/mod_flv_streaming.c b/src/mod_flv_streaming.c
index c0b1dd6..f8bf999 100644
--- a/src/mod_flv_streaming.c
+++ b/src/mod_flv_streaming.c
@@ -265,6 +265,7 @@ URIHANDLER_FUNC(mod_flv_streaming_path_handler) {
/* this function is called at dlopen() time and inits the callbacks */
+int mod_flv_streaming_plugin_init(plugin *p);
int mod_flv_streaming_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("flv_streaming");
diff --git a/src/mod_indexfile.c b/src/mod_indexfile.c
index 36b9e45..d133474 100644
--- a/src/mod_indexfile.c
+++ b/src/mod_indexfile.c
@@ -206,6 +206,7 @@ URIHANDLER_FUNC(mod_indexfile_subrequest) {
/* this function is called at dlopen() time and inits the callbacks */
+int mod_indexfile_plugin_init(plugin *p);
int mod_indexfile_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("indexfile");
diff --git a/src/mod_magnet.c b/src/mod_magnet.c
index 02bcaed..b8da992 100644
--- a/src/mod_magnet.c
+++ b/src/mod_magnet.c
@@ -365,6 +365,8 @@ typedef struct {
MAGNET_ENV_REQUEST_METHOD,
MAGNET_ENV_REQUEST_URI,
MAGNET_ENV_REQUEST_ORIG_URI,
+ MAGNET_ENV_REQUEST_PATH_INFO,
+ MAGNET_ENV_REQUEST_REMOTE_IP,
MAGNET_ENV_REQUEST_PROTOCOL
} type;
} magnet_env_t;
@@ -387,6 +389,8 @@ static buffer *magnet_env_get_buffer(server *srv, connection *con, const char *k
{ "request.method", MAGNET_ENV_REQUEST_METHOD },
{ "request.uri", MAGNET_ENV_REQUEST_URI },
{ "request.orig-uri", MAGNET_ENV_REQUEST_ORIG_URI },
+ { "request.path-info", MAGNET_ENV_REQUEST_PATH_INFO },
+ { "request.remote-ip", MAGNET_ENV_REQUEST_REMOTE_IP },
{ "request.protocol", MAGNET_ENV_REQUEST_PROTOCOL },
{ NULL, MAGNET_ENV_UNSET }
@@ -420,6 +424,8 @@ static buffer *magnet_env_get_buffer(server *srv, connection *con, const char *k
break;
case MAGNET_ENV_REQUEST_URI: dest = con->request.uri; break;
case MAGNET_ENV_REQUEST_ORIG_URI: dest = con->request.orig_uri; break;
+ case MAGNET_ENV_REQUEST_PATH_INFO: dest = con->request.pathinfo; break;
+ case MAGNET_ENV_REQUEST_REMOTE_IP: dest = con->dst_addr_buf; break;
case MAGNET_ENV_REQUEST_PROTOCOL:
buffer_copy_string(srv->tmp_buf, get_http_version_name(con->request.http_version));
dest = srv->tmp_buf;
@@ -489,6 +495,42 @@ static int magnet_env_set(lua_State *L) {
}
+static int magnet_cgi_get(lua_State *L) {
+ connection *con;
+ data_string *ds;
+
+ const char *key = luaL_checkstring(L, 2);
+
+ lua_pushstring(L, "lighty.con");
+ lua_gettable(L, LUA_REGISTRYINDEX);
+ con = lua_touserdata(L, -1);
+ lua_pop(L, 1);
+
+ if (NULL != (ds = (data_string *)array_get_element(con->environment, key)) && ds->value->used)
+ lua_pushlstring(L, CONST_BUF_LEN(ds->value));
+ else
+ lua_pushnil(L);
+
+ return 1;
+}
+
+static int magnet_cgi_set(lua_State *L) {
+ connection *con;
+
+ const char *key = luaL_checkstring(L, 2);
+ const char *val = luaL_checkstring(L, 3);
+
+ lua_pushstring(L, "lighty.con");
+ lua_gettable(L, LUA_REGISTRYINDEX);
+ con = lua_touserdata(L, -1);
+ lua_pop(L, 1);
+
+ array_set_key_value(con->environment, key, strlen(key), val, strlen(val));
+
+ return 0;
+}
+
+
static int magnet_copy_response_header(server *srv, connection *con, plugin_data *p, lua_State *L) {
UNUSED(p);
/**
@@ -711,6 +753,15 @@ static handler_t magnet_attract(server *srv, connection *con, plugin_data *p, bu
lua_newtable(L); /* {} (sp += 1) */
lua_newtable(L); /* the meta-table for the request-table (sp += 1) */
+ lua_pushcfunction(L, magnet_cgi_get); /* (sp += 1) */
+ lua_setfield(L, -2, "__index"); /* (sp -= 1) */
+ lua_pushcfunction(L, magnet_cgi_set); /* (sp += 1) */
+ lua_setfield(L, -2, "__newindex"); /* (sp -= 1) */
+ lua_setmetatable(L, -2); /* tie the metatable to req_env (sp -= 1) */
+ lua_setfield(L, -2, "req_env"); /* content = {} (sp -= 1) */
+
+ lua_newtable(L); /* {} (sp += 1) */
+ lua_newtable(L); /* the meta-table for the request-table (sp += 1) */
lua_pushcfunction(L, magnet_status_get); /* (sp += 1) */
lua_setfield(L, -2, "__index"); /* (sp -= 1) */
lua_pushcfunction(L, magnet_status_set); /* (sp += 1) */
@@ -840,6 +891,7 @@ URIHANDLER_FUNC(mod_magnet_physical) {
/* this function is called at dlopen() time and inits the callbacks */
+int mod_magnet_plugin_init(plugin *p);
int mod_magnet_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("magnet");
@@ -856,6 +908,7 @@ int mod_magnet_plugin_init(plugin *p) {
}
#else
+int mod_magnet_plugin_init(plugin *p);
int mod_magnet_plugin_init(plugin *p) {
UNUSED(p);
return -1;
diff --git a/src/mod_magnet_cache.c b/src/mod_magnet_cache.c
index 3756bd1..1e4840f 100644
--- a/src/mod_magnet_cache.c
+++ b/src/mod_magnet_cache.c
@@ -9,7 +9,7 @@
#include <lualib.h>
#include <lauxlib.h>
-script *script_init() {
+static script *script_init() {
script *sc;
sc = calloc(1, sizeof(*sc));
@@ -19,7 +19,7 @@ script *script_init() {
return sc;
}
-void script_free(script *sc) {
+static void script_free(script *sc) {
if (!sc) return;
lua_pop(sc->L, 1); /* the function copy */
diff --git a/src/mod_mysql_vhost.c b/src/mod_mysql_vhost.c
index 2824055..7c81067 100644
--- a/src/mod_mysql_vhost.c
+++ b/src/mod_mysql_vhost.c
@@ -422,6 +422,7 @@ ERR500: if (result) mysql_free_result(result);
}
/* this function is called at dlopen() time and inits the callbacks */
+int mod_mysql_vhost_plugin_init(plugin *p);
int mod_mysql_vhost_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("mysql_vhost");
@@ -437,6 +438,7 @@ int mod_mysql_vhost_plugin_init(plugin *p) {
}
#else
/* we don't have mysql support, this plugin does nothing */
+int mod_mysql_vhost_plugin_init(plugin *p);
int mod_mysql_vhost_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("mysql_vhost");
diff --git a/src/mod_proxy.c b/src/mod_proxy.c
index 92549e2..5f6a7da 100644
--- a/src/mod_proxy.c
+++ b/src/mod_proxy.c
@@ -332,7 +332,7 @@ SETDEFAULTS_FUNC(mod_proxy_set_defaults) {
return HANDLER_GO_ON;
}
-void proxy_connection_close(server *srv, handler_ctx *hctx) {
+static void proxy_connection_close(server *srv, handler_ctx *hctx) {
plugin_data *p;
connection *con;
@@ -356,20 +356,35 @@ void proxy_connection_close(server *srv, handler_ctx *hctx) {
static int proxy_establish_connection(server *srv, handler_ctx *hctx) {
struct sockaddr *proxy_addr;
struct sockaddr_in proxy_addr_in;
+#if defined(HAVE_IPV6) && defined(HAVE_INET_PTON)
+ struct sockaddr_in6 proxy_addr_in6;
+#endif
socklen_t servlen;
plugin_data *p = hctx->plugin_data;
data_proxy *host= hctx->host;
int proxy_fd = hctx->fd;
- memset(&proxy_addr, 0, sizeof(proxy_addr));
- proxy_addr_in.sin_family = AF_INET;
- proxy_addr_in.sin_addr.s_addr = inet_addr(host->host->ptr);
- proxy_addr_in.sin_port = htons(host->port);
- servlen = sizeof(proxy_addr_in);
+#if defined(HAVE_IPV6) && defined(HAVE_INET_PTON)
+ if (strstr(host->host->ptr, ":")) {
+ memset(&proxy_addr_in6, 0, sizeof(proxy_addr_in6));
+ proxy_addr_in6.sin6_family = AF_INET6;
+ inet_pton(AF_INET6, host->host->ptr, (char *) &proxy_addr_in6.sin6_addr);
+ proxy_addr_in6.sin6_port = htons(host->port);
+ servlen = sizeof(proxy_addr_in6);
+ proxy_addr = (struct sockaddr *) &proxy_addr_in6;
+ } else
+#endif
+ {
+ memset(&proxy_addr_in, 0, sizeof(proxy_addr_in));
+ proxy_addr_in.sin_family = AF_INET;
+ proxy_addr_in.sin_addr.s_addr = inet_addr(host->host->ptr);
+ proxy_addr_in.sin_port = htons(host->port);
+ servlen = sizeof(proxy_addr_in);
+ proxy_addr = (struct sockaddr *) &proxy_addr_in;
+ }
- proxy_addr = (struct sockaddr *) &proxy_addr_in;
if (-1 == connect(proxy_fd, proxy_addr, servlen)) {
if (errno == EINPROGRESS || errno == EALREADY) {
@@ -395,7 +410,7 @@ static int proxy_establish_connection(server *srv, handler_ctx *hctx) {
return 0;
}
-void proxy_set_header(connection *con, const char *key, const char *value) {
+static void proxy_set_header(connection *con, const char *key, const char *value) {
data_string *ds_dst;
if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
@@ -407,7 +422,7 @@ void proxy_set_header(connection *con, const char *key, const char *value) {
array_insert_unique(con->request.headers, (data_unset *)ds_dst);
}
-void proxy_append_header(connection *con, const char *key, const char *value) {
+static void proxy_append_header(connection *con, const char *key, const char *value) {
data_string *ds_dst;
if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
@@ -741,9 +756,16 @@ static handler_t proxy_write_request(server *srv, handler_ctx *hctx) {
switch(hctx->state) {
case PROXY_STATE_INIT:
- if (-1 == (hctx->fd = socket(AF_INET, SOCK_STREAM, 0))) {
+ if (strstr(host->host->ptr,":")) {
+ if (-1 == (hctx->fd = socket(AF_INET6, SOCK_STREAM, 0))) {
+ log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed: ", strerror(errno));
+ return HANDLER_ERROR;
+ }
+ } else {
+ if (-1 == (hctx->fd = socket(AF_INET, SOCK_STREAM, 0))) {
log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed: ", strerror(errno));
return HANDLER_ERROR;
+ }
}
hctx->fde_ndx = -1;
@@ -1209,7 +1231,7 @@ static handler_t mod_proxy_check_extension(server *srv, connection *con, void *p
if (ndx >= (int) extension->value->used) {
/* didn't found a higher id, wrap to the start */
- for (ndx = 0; ndx < (int) k; ndx++) {
+ for (ndx = 0; ndx <= (int) k; ndx++) {
host = (data_proxy *)extension->value->data[ndx];
if (!host->is_disabled) break;
}
@@ -1321,6 +1343,7 @@ TRIGGER_FUNC(mod_proxy_trigger) {
}
+int mod_proxy_plugin_init(plugin *p);
int mod_proxy_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("proxy");
diff --git a/src/mod_redirect.c b/src/mod_redirect.c
index d5f7864..59b129d 100644
--- a/src/mod_redirect.c
+++ b/src/mod_redirect.c
@@ -271,6 +271,7 @@ static handler_t mod_redirect_uri_handler(server *srv, connection *con, void *p_
}
+int mod_redirect_plugin_init(plugin *p);
int mod_redirect_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("redirect");
diff --git a/src/mod_rewrite.c b/src/mod_rewrite.c
index 1b90afc..6dc5707 100644
--- a/src/mod_rewrite.c
+++ b/src/mod_rewrite.c
@@ -63,7 +63,7 @@ static void handler_ctx_free(handler_ctx *hctx) {
free(hctx);
}
-rewrite_rule_buffer *rewrite_rule_buffer_init(void) {
+static rewrite_rule_buffer *rewrite_rule_buffer_init(void) {
rewrite_rule_buffer *kvb;
kvb = calloc(1, sizeof(*kvb));
@@ -71,7 +71,7 @@ rewrite_rule_buffer *rewrite_rule_buffer_init(void) {
return kvb;
}
-int rewrite_rule_buffer_append(rewrite_rule_buffer *kvb, buffer *key, buffer *value, int once) {
+static int rewrite_rule_buffer_append(rewrite_rule_buffer *kvb, buffer *key, buffer *value, int once) {
#ifdef HAVE_PCRE_H
size_t i;
const char *errptr;
@@ -121,7 +121,7 @@ int rewrite_rule_buffer_append(rewrite_rule_buffer *kvb, buffer *key, buffer *va
#endif
}
-void rewrite_rule_buffer_free(rewrite_rule_buffer *kvb) {
+static void rewrite_rule_buffer_free(rewrite_rule_buffer *kvb) {
#ifdef HAVE_PCRE_H
size_t i;
@@ -444,6 +444,7 @@ URIHANDLER_FUNC(mod_rewrite_uri_handler) {
return HANDLER_GO_ON;
}
+int mod_rewrite_plugin_init(plugin *p);
int mod_rewrite_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("rewrite");
diff --git a/src/mod_rrdtool.c b/src/mod_rrdtool.c
index 2cb4640..41095d3 100644
--- a/src/mod_rrdtool.c
+++ b/src/mod_rrdtool.c
@@ -91,7 +91,7 @@ FREE_FUNC(mod_rrd_free) {
return HANDLER_GO_ON;
}
-int mod_rrd_create_pipe(server *srv, plugin_data *p) {
+static int mod_rrd_create_pipe(server *srv, plugin_data *p) {
#ifdef HAVE_FORK
pid_t pid;
@@ -230,6 +230,7 @@ static ssize_t safe_read(int fd, void *buf, size_t count) {
static int mod_rrdtool_create_rrd(server *srv, plugin_data *p, plugin_config *s) {
struct stat st;
+ int r;
/* check if DB already exists */
if (0 == stat(s->path_rrd->ptr, &st)) {
@@ -239,54 +240,57 @@ static int mod_rrdtool_create_rrd(server *srv, plugin_data *p, plugin_config *s)
"not a regular file:", s->path_rrd);
return HANDLER_ERROR;
}
- } else {
- int r ;
- /* create a new one */
+ }
- buffer_copy_string_len(p->cmd, CONST_STR_LEN("create "));
- buffer_append_string_buffer(p->cmd, s->path_rrd);
- buffer_append_string_len(p->cmd, CONST_STR_LEN(
- " --step 60 "
- "DS:InOctets:ABSOLUTE:600:U:U "
- "DS:OutOctets:ABSOLUTE:600:U:U "
- "DS:Requests:ABSOLUTE:600:U:U "
- "RRA:AVERAGE:0.5:1:600 "
- "RRA:AVERAGE:0.5:6:700 "
- "RRA:AVERAGE:0.5:24:775 "
- "RRA:AVERAGE:0.5:288:797 "
- "RRA:MAX:0.5:1:600 "
- "RRA:MAX:0.5:6:700 "
- "RRA:MAX:0.5:24:775 "
- "RRA:MAX:0.5:288:797 "
- "RRA:MIN:0.5:1:600 "
- "RRA:MIN:0.5:6:700 "
- "RRA:MIN:0.5:24:775 "
- "RRA:MIN:0.5:288:797\n"));
+ /* still create DB if it's empty file */
+ if (st.st_size > 0) {
+ return HANDLER_GO_ON;
+ }
- if (-1 == (r = safe_write(p->write_fd, p->cmd->ptr, p->cmd->used - 1))) {
- log_error_write(srv, __FILE__, __LINE__, "ss",
- "rrdtool-write: failed", strerror(errno));
+ /* create a new one */
+ buffer_copy_string_len(p->cmd, CONST_STR_LEN("create "));
+ buffer_append_string_buffer(p->cmd, s->path_rrd);
+ buffer_append_string_len(p->cmd, CONST_STR_LEN(
+ " --step 60 "
+ "DS:InOctets:ABSOLUTE:600:U:U "
+ "DS:OutOctets:ABSOLUTE:600:U:U "
+ "DS:Requests:ABSOLUTE:600:U:U "
+ "RRA:AVERAGE:0.5:1:600 "
+ "RRA:AVERAGE:0.5:6:700 "
+ "RRA:AVERAGE:0.5:24:775 "
+ "RRA:AVERAGE:0.5:288:797 "
+ "RRA:MAX:0.5:1:600 "
+ "RRA:MAX:0.5:6:700 "
+ "RRA:MAX:0.5:24:775 "
+ "RRA:MAX:0.5:288:797 "
+ "RRA:MIN:0.5:1:600 "
+ "RRA:MIN:0.5:6:700 "
+ "RRA:MIN:0.5:24:775 "
+ "RRA:MIN:0.5:288:797\n"));
+
+ if (-1 == (r = safe_write(p->write_fd, p->cmd->ptr, p->cmd->used - 1))) {
+ log_error_write(srv, __FILE__, __LINE__, "ss",
+ "rrdtool-write: failed", strerror(errno));
- return HANDLER_ERROR;
- }
+ return HANDLER_ERROR;
+ }
- buffer_prepare_copy(p->resp, 4096);
- if (-1 == (r = safe_read(p->read_fd, p->resp->ptr, p->resp->size))) {
- log_error_write(srv, __FILE__, __LINE__, "ss",
- "rrdtool-read: failed", strerror(errno));
+ buffer_prepare_copy(p->resp, 4096);
+ if (-1 == (r = safe_read(p->read_fd, p->resp->ptr, p->resp->size))) {
+ log_error_write(srv, __FILE__, __LINE__, "ss",
+ "rrdtool-read: failed", strerror(errno));
- return HANDLER_ERROR;
- }
+ return HANDLER_ERROR;
+ }
- p->resp->used = r;
+ p->resp->used = r;
- if (p->resp->ptr[0] != 'O' ||
- p->resp->ptr[1] != 'K') {
- log_error_write(srv, __FILE__, __LINE__, "sbb",
- "rrdtool-response:", p->cmd, p->resp);
+ if (p->resp->ptr[0] != 'O' ||
+ p->resp->ptr[1] != 'K') {
+ log_error_write(srv, __FILE__, __LINE__, "sbb",
+ "rrdtool-response:", p->cmd, p->resp);
- return HANDLER_ERROR;
- }
+ return HANDLER_ERROR;
}
return HANDLER_GO_ON;
@@ -477,6 +481,7 @@ REQUESTDONE_FUNC(mod_rrd_account) {
return HANDLER_GO_ON;
}
+int mod_rrdtool_plugin_init(plugin *p);
int mod_rrdtool_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("rrd");
diff --git a/src/mod_scgi.c b/src/mod_scgi.c
index 0d19a88..e92a516 100644
--- a/src/mod_scgi.c
+++ b/src/mod_scgi.c
@@ -38,6 +38,8 @@
#include <sys/wait.h>
#endif
+#include "version.h"
+
enum {EOL_UNSET, EOL_N, EOL_RN};
/*
@@ -372,7 +374,7 @@ static void handler_ctx_free(handler_ctx *hctx) {
free(hctx);
}
-scgi_proc *scgi_process_init() {
+static scgi_proc *scgi_process_init() {
scgi_proc *f;
f = calloc(1, sizeof(*f));
@@ -384,7 +386,7 @@ scgi_proc *scgi_process_init() {
return f;
}
-void scgi_process_free(scgi_proc *f) {
+static void scgi_process_free(scgi_proc *f) {
if (!f) return;
scgi_process_free(f->next);
@@ -394,7 +396,7 @@ void scgi_process_free(scgi_proc *f) {
free(f);
}
-scgi_extension_host *scgi_host_init() {
+static scgi_extension_host *scgi_host_init() {
scgi_extension_host *f;
f = calloc(1, sizeof(*f));
@@ -409,7 +411,7 @@ scgi_extension_host *scgi_host_init() {
return f;
}
-void scgi_host_free(scgi_extension_host *h) {
+static void scgi_host_free(scgi_extension_host *h) {
if (!h) return;
buffer_free(h->host);
@@ -426,7 +428,7 @@ void scgi_host_free(scgi_extension_host *h) {
}
-scgi_exts *scgi_extensions_init() {
+static scgi_exts *scgi_extensions_init() {
scgi_exts *f;
f = calloc(1, sizeof(*f));
@@ -434,7 +436,7 @@ scgi_exts *scgi_extensions_init() {
return f;
}
-void scgi_extensions_free(scgi_exts *f) {
+static void scgi_extensions_free(scgi_exts *f) {
size_t i;
if (!f) return;
@@ -464,7 +466,7 @@ void scgi_extensions_free(scgi_exts *f) {
free(f);
}
-int scgi_extension_insert(scgi_exts *ext, buffer *key, scgi_extension_host *fh) {
+static int scgi_extension_insert(scgi_exts *ext, buffer *key, scgi_extension_host *fh) {
scgi_extension *fe;
size_t i;
@@ -1178,7 +1180,7 @@ static int scgi_set_state(server *srv, handler_ctx *hctx, scgi_connection_state_
}
-void scgi_connection_cleanup(server *srv, handler_ctx *hctx) {
+static void scgi_connection_cleanup(server *srv, handler_ctx *hctx) {
plugin_data *p;
connection *con;
@@ -1281,10 +1283,11 @@ static int scgi_env_add(buffer *env, const char *key, size_t key_len, const char
buffer_prepare_append(env, len);
- /* include the NUL */
- memcpy(env->ptr + env->used, key, key_len + 1);
+ memcpy(env->ptr + env->used, key, key_len);
+ env->ptr[env->used + key_len] = '\0';
env->used += key_len + 1;
- memcpy(env->ptr + env->used, val, val_len + 1);
+ memcpy(env->ptr + env->used, val, val_len);
+ env->ptr[env->used + val_len] = '\0';
env->used += val_len + 1;
return 0;
@@ -1461,10 +1464,18 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
scgi_env_add(p->scgi_env, CONST_STR_LEN("SCGI"), CONST_STR_LEN("1"));
- scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_NAME"/"PACKAGE_VERSION));
+ if (buffer_is_empty(con->conf.server_tag)) {
+ scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_STR_LEN(PACKAGE_DESC));
+ } else {
+ scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_SOFTWARE"), CONST_BUF_LEN(con->conf.server_tag));
+ }
if (con->server_name->used) {
- scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_NAME"), CONST_BUF_LEN(con->server_name));
+ size_t len = con->server_name->used - 1;
+ char *colon = strchr(con->server_name->ptr, ':');
+ if (colon) len = colon - con->server_name->ptr;
+
+ scgi_env_add(p->scgi_env, CONST_STR_LEN("SERVER_NAME"), con->server_name->ptr, len);
} else {
#ifdef HAVE_IPV6
s = inet_ntop(srv_sock->addr.plain.sa_family,
@@ -1915,7 +1926,7 @@ static int scgi_demux_response(server *srv, handler_ctx *hctx) {
}
-int scgi_proclist_sort_up(server *srv, scgi_extension_host *host, scgi_proc *proc) {
+static int scgi_proclist_sort_up(server *srv, scgi_extension_host *host, scgi_proc *proc) {
scgi_proc *p;
UNUSED(srv);
@@ -2827,7 +2838,11 @@ static handler_t scgi_check_extension(server *srv, connection *con, void *p_d, i
*/
/* the rewrite is only done for /prefix/? matches */
- if (extension->key->ptr[0] == '/' &&
+ if (host->fix_root_path_name && extension->key->ptr[0] == '/' && extension->key->ptr[1] == '\0') {
+ buffer_copy_string(con->request.pathinfo, con->uri.path->ptr);
+ con->uri.path->used = 1;
+ con->uri.path->ptr[con->uri.path->used - 1] = '\0';
+ } else if (extension->key->ptr[0] == '/' &&
con->uri.path->used > extension->key->used &&
NULL != (pathinfo = strchr(con->uri.path->ptr + extension->key->used - 1, '/'))) {
/* rewrite uri.path and pathinfo */
@@ -2836,10 +2851,6 @@ static handler_t scgi_check_extension(server *srv, connection *con, void *p_d, i
con->uri.path->used -= con->request.pathinfo->used - 1;
con->uri.path->ptr[con->uri.path->used - 1] = '\0';
- } else if (host->fix_root_path_name && extension->key->ptr[0] == '/' && extension->key->ptr[1] == '\0') {
- buffer_copy_string(con->request.pathinfo, con->uri.path->ptr);
- con->uri.path->used = 1;
- con->uri.path->ptr[con->uri.path->used - 1] = '\0';
}
}
} else {
@@ -3105,6 +3116,7 @@ TRIGGER_FUNC(mod_scgi_handle_trigger) {
}
+int mod_scgi_plugin_init(plugin *p);
int mod_scgi_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("scgi");
diff --git a/src/mod_secure_download.c b/src/mod_secure_download.c
index 0ff0102..ca1f13e 100644
--- a/src/mod_secure_download.c
+++ b/src/mod_secure_download.c
@@ -138,7 +138,7 @@ SETDEFAULTS_FUNC(mod_secdownload_set_defaults) {
* @return if the supplied string is a valid MD5 string 1 is returned otherwise 0
*/
-int is_hex_len(const char *str, size_t len) {
+static int is_hex_len(const char *str, size_t len) {
size_t i;
if (NULL == str) return 0;
@@ -293,6 +293,7 @@ URIHANDLER_FUNC(mod_secdownload_uri_handler) {
/* this function is called at dlopen() time and inits the callbacks */
+int mod_secdownload_plugin_init(plugin *p);
int mod_secdownload_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("secdownload");
diff --git a/src/mod_setenv.c b/src/mod_setenv.c
index 88ce45a..a072466 100644
--- a/src/mod_setenv.c
+++ b/src/mod_setenv.c
@@ -230,6 +230,7 @@ REQUESTDONE_FUNC(mod_setenv_reset) {
/* this function is called at dlopen() time and inits the callbacks */
+int mod_setenv_plugin_init(plugin *p);
int mod_setenv_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("setenv");
diff --git a/src/mod_simple_vhost.c b/src/mod_simple_vhost.c
index 1a8c13a..21d0107 100644
--- a/src/mod_simple_vhost.c
+++ b/src/mod_simple_vhost.c
@@ -270,6 +270,7 @@ static handler_t mod_simple_vhost_docroot(server *srv, connection *con, void *p_
}
+int mod_simple_vhost_plugin_init(plugin *p);
int mod_simple_vhost_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("simple_vhost");
diff --git a/src/mod_ssi.c b/src/mod_ssi.c
index 8323c8e..07554bc 100644
--- a/src/mod_ssi.c
+++ b/src/mod_ssi.c
@@ -37,6 +37,7 @@
#endif
#include "etag.h"
+#include "version.h"
/* The newest modified time of included files for include statement */
static volatile time_t include_file_last_mtime = 0;
@@ -69,6 +70,7 @@ FREE_FUNC(mod_ssi_free) {
plugin_config *s = p->config_storage[i];
array_free(s->ssi_extension);
+ buffer_free(s->content_type);
free(s);
}
@@ -100,6 +102,7 @@ SETDEFAULTS_FUNC(mod_ssi_set_defaults) {
config_values_t cv[] = {
{ "ssi.extension", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
+ { "ssi.content-type", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
{ NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
};
@@ -112,8 +115,10 @@ SETDEFAULTS_FUNC(mod_ssi_set_defaults) {
s = calloc(1, sizeof(plugin_config));
s->ssi_extension = array_init();
+ s->content_type = buffer_init();
cv[0].destination = s->ssi_extension;
+ cv[1].destination = s->content_type;
p->config_storage[i] = s;
@@ -139,7 +144,7 @@ SETDEFAULTS_FUNC(mod_ssi_set_defaults) {
return HANDLER_GO_ON;
}
-int ssi_env_add(array *env, const char *key, const char *val) {
+static int ssi_env_add(array *env, const char *key, const char *val) {
data_string *ds;
if (NULL == (ds = (data_string *)array_get_unused_element(env, TYPE_STRING))) {
@@ -199,6 +204,34 @@ static int ssi_env_add_request_headers(server *srv, connection *con, plugin_data
}
}
+ for (i = 0; i < con->environment->used; i++) {
+ data_string *ds;
+
+ ds = (data_string *)con->environment->data[i];
+
+ if (ds->value->used && ds->key->used) {
+ size_t j;
+
+ buffer_reset(srv->tmp_buf);
+ buffer_prepare_append(srv->tmp_buf, ds->key->used + 2);
+
+ for (j = 0; j < ds->key->used - 1; j++) {
+ char c = '_';
+ if (light_isalpha(ds->key->ptr[j])) {
+ /* upper-case */
+ c = ds->key->ptr[j] & ~32;
+ } else if (light_isdigit(ds->key->ptr[j])) {
+ /* copy */
+ c = ds->key->ptr[j];
+ }
+ srv->tmp_buf->ptr[srv->tmp_buf->used++] = c;
+ }
+ srv->tmp_buf->ptr[srv->tmp_buf->used] = '\0';
+
+ ssi_env_add(p->ssi_cgi_env, srv->tmp_buf->ptr, ds->value->ptr);
+ }
+ }
+
return 0;
}
@@ -216,7 +249,7 @@ static int build_ssi_cgi_vars(server *srv, connection *con, plugin_data *p) {
array_reset(p->ssi_cgi_env);
- ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_SOFTWARE"), PACKAGE_NAME"/"PACKAGE_VERSION);
+ ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_SOFTWARE"), PACKAGE_DESC);
ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_NAME"),
#ifdef HAVE_IPV6
inet_ntop(srv_sock->addr.plain.sa_family,
@@ -656,17 +689,22 @@ static int process_ssi_stmt(server *srv, connection *con, plugin_data *p,
if (p->if_is_false) break;
b = chunkqueue_get_append_buffer(con->write_queue);
- buffer_copy_string_len(b, CONST_STR_LEN("<pre>"));
for (i = 0; i < p->ssi_vars->used; i++) {
data_string *ds = (data_string *)p->ssi_vars->data[p->ssi_vars->sorted[i]];
buffer_append_string_buffer(b, ds->key);
- buffer_append_string_len(b, CONST_STR_LEN(": "));
- buffer_append_string_buffer(b, ds->value);
- buffer_append_string_len(b, CONST_STR_LEN("<br />"));
+ buffer_append_string_len(b, CONST_STR_LEN("="));
+ buffer_append_string_encoded(b, CONST_BUF_LEN(ds->value), ENCODING_MINIMAL_XML);
+ buffer_append_string_len(b, CONST_STR_LEN("\n"));
+ }
+ for (i = 0; i < p->ssi_cgi_env->used; i++) {
+ data_string *ds = (data_string *)p->ssi_cgi_env->data[p->ssi_cgi_env->sorted[i]];
+ buffer_append_string_buffer(b, ds->key);
+ buffer_append_string_len(b, CONST_STR_LEN("="));
+ buffer_append_string_encoded(b, CONST_BUF_LEN(ds->value), ENCODING_MINIMAL_XML);
+ buffer_append_string_len(b, CONST_STR_LEN("\n"));
}
- buffer_append_string_len(b, CONST_STR_LEN("</pre>"));
break;
case SSI_EXEC: {
@@ -1029,7 +1067,11 @@ static int mod_ssi_handle_request(server *srv, connection *con, plugin_data *p)
con->file_finished = 1;
con->mode = p->id;
- response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
+ if (p->conf.content_type->used <= 1) {
+ response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
+ } else {
+ response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(p->conf.content_type));
+ }
{
/* Generate "ETag" & "Last-Modified" headers */
@@ -1068,6 +1110,7 @@ static int mod_ssi_patch_connection(server *srv, connection *con, plugin_data *p
plugin_config *s = p->config_storage[0];
PATCH(ssi_extension);
+ PATCH(content_type);
/* skip the first, the global context */
for (i = 1; i < srv->config_context->used; i++) {
@@ -1083,6 +1126,8 @@ static int mod_ssi_patch_connection(server *srv, connection *con, plugin_data *p
if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssi.extension"))) {
PATCH(ssi_extension);
+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssi.content-type"))) {
+ PATCH(content_type);
}
}
}
@@ -1125,6 +1170,7 @@ URIHANDLER_FUNC(mod_ssi_physical_path) {
/* this function is called at dlopen() time and inits the callbacks */
+int mod_ssi_plugin_init(plugin *p);
int mod_ssi_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("ssi");
diff --git a/src/mod_ssi.h b/src/mod_ssi.h
index 4d2214b..241e832 100644
--- a/src/mod_ssi.h
+++ b/src/mod_ssi.h
@@ -15,6 +15,7 @@
typedef struct {
array *ssi_extension;
+ buffer *content_type;
} plugin_config;
typedef struct {
diff --git a/src/mod_staticfile.c b/src/mod_staticfile.c
index 37f1b26..df19d67 100644
--- a/src/mod_staticfile.c
+++ b/src/mod_staticfile.c
@@ -532,6 +532,7 @@ URIHANDLER_FUNC(mod_staticfile_subrequest) {
/* this function is called at dlopen() time and inits the callbacks */
+int mod_staticfile_plugin_init(plugin *p);
int mod_staticfile_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("staticfile");
diff --git a/src/mod_status.c b/src/mod_status.c
index 3f8b120..7548276 100644
--- a/src/mod_status.c
+++ b/src/mod_status.c
@@ -18,6 +18,7 @@
#include "plugin.h"
#include "inet_ntop_cache.h"
+#include "version.h"
typedef struct {
buffer *config_url;
@@ -701,7 +702,7 @@ static handler_t mod_status_handle_server_config(server *srv, connection *con, v
" <title>Status</title>\n"
" </head>\n"
" <body>\n"
- " <h1>" PACKAGE_NAME " " PACKAGE_VERSION "</h1>\n"
+ " <h1>" PACKAGE_DESC "</h1>\n"
" <table summary=\"status\" border=\"1\">\n"));
mod_status_header_append(b, "Server-Features");
@@ -853,6 +854,7 @@ REQUESTDONE_FUNC(mod_status_account) {
return HANDLER_GO_ON;
}
+int mod_status_plugin_init(plugin *p);
int mod_status_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("status");
diff --git a/src/mod_trigger_b4_dl.c b/src/mod_trigger_b4_dl.c
index 11fc2ae..44f5db6 100644
--- a/src/mod_trigger_b4_dl.c
+++ b/src/mod_trigger_b4_dl.c
@@ -576,6 +576,7 @@ TRIGGER_FUNC(mod_trigger_b4_dl_handle_trigger) {
/* this function is called at dlopen() time and inits the callbacks */
+int mod_trigger_b4_dl_plugin_init(plugin *p);
int mod_trigger_b4_dl_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("trigger_b4_dl");
diff --git a/src/mod_userdir.c b/src/mod_userdir.c
index 7ac5cc1..ebdabc7 100644
--- a/src/mod_userdir.c
+++ b/src/mod_userdir.c
@@ -314,6 +314,7 @@ URIHANDLER_FUNC(mod_userdir_docroot_handler) {
/* this function is called at dlopen() time and inits the callbacks */
+int mod_userdir_plugin_init(plugin *p);
int mod_userdir_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("userdir");
diff --git a/src/mod_usertrack.c b/src/mod_usertrack.c
index c85f36c..246bb98 100644
--- a/src/mod_usertrack.c
+++ b/src/mod_usertrack.c
@@ -229,6 +229,7 @@ URIHANDLER_FUNC(mod_usertrack_uri_handler) {
/* we assume sizeof(time_t) == 4 here, but if not it ain't a problem at all */
LI_ltostr(hh, srv->cur_ts);
MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
+ MD5_Update(&Md5Ctx, (unsigned char *)srv->entropy, sizeof(srv->entropy));
LI_ltostr(hh, rand());
MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
@@ -255,6 +256,7 @@ URIHANDLER_FUNC(mod_usertrack_uri_handler) {
/* this function is called at dlopen() time and inits the callbacks */
+int mod_usertrack_plugin_init(plugin *p);
int mod_usertrack_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("usertrack");
diff --git a/src/mod_webdav.c b/src/mod_webdav.c
index a2376c0..a78b960 100644
--- a/src/mod_webdav.c
+++ b/src/mod_webdav.c
@@ -1096,7 +1096,7 @@ static int webdav_parse_chunkqueue(server *srv, connection *con, plugin_data *p,
}
#endif
-int webdav_lockdiscovery(server *srv, connection *con,
+static int webdav_lockdiscovery(server *srv, connection *con,
buffer *locktoken, const char *lockscope, const char *locktype, int depth) {
buffer *b;
@@ -1156,7 +1156,7 @@ int webdav_lockdiscovery(server *srv, connection *con,
*
*
*/
-int webdav_has_lock(server *srv, connection *con, plugin_data *p, buffer *uri) {
+static int webdav_has_lock(server *srv, connection *con, plugin_data *p, buffer *uri) {
int has_lock = 1;
#ifdef USE_LOCKS
@@ -2474,6 +2474,7 @@ propmatch_cleanup:
/* this function is called at dlopen() time and inits the callbacks */
+int mod_webdav_plugin_init(plugin *p);
int mod_webdav_plugin_init(plugin *p) {
p->version = LIGHTTPD_VERSION_ID;
p->name = buffer_init_string("webdav");
diff --git a/src/network.c b/src/network.c
index 0534bee..e2d5f0b 100644
--- a/src/network.c
+++ b/src/network.c
@@ -26,7 +26,7 @@
# include <openssl/rand.h>
#endif
-handler_t network_server_handle_fdevent(void *s, void *context, int revents) {
+static handler_t network_server_handle_fdevent(void *s, void *context, int revents) {
server *srv = (server *)s;
server_socket *srv_socket = (server_socket *)context;
connection *con;
@@ -62,7 +62,7 @@ handler_t network_server_handle_fdevent(void *s, void *context, int revents) {
return HANDLER_GO_ON;
}
-int network_server_init(server *srv, buffer *host_token, specific_config *s) {
+static int network_server_init(server *srv, buffer *host_token, specific_config *s) {
int val;
socklen_t addr_len;
server_socket *srv_socket;
@@ -73,10 +73,6 @@ int network_server_init(server *srv, buffer *host_token, specific_config *s) {
int is_unix_domain_socket = 0;
int fd;
-#ifdef SO_ACCEPTFILTER
- struct accept_filter_arg afa;
-#endif
-
#ifdef __WIN32
WORD wVersionRequested;
WSADATA wsaData;
@@ -396,12 +392,17 @@ int network_server_init(server *srv, buffer *host_token, specific_config *s) {
return -1;
#endif
+#ifdef TCP_DEFER_ACCEPT
+ } else if (s->defer_accept) {
+ int v = s->defer_accept;
+ if (-1 == setsockopt(srv_socket->fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &v, sizeof(v))) {
+ log_error_write(srv, __FILE__, __LINE__, "ss", "can't set TCP_DEFER_ACCEPT: ", strerror(errno));
+ }
+#endif
} else {
#ifdef SO_ACCEPTFILTER
- /*
- * FreeBSD accf_http filter
- *
- */
+ /* FreeBSD accf_http filter */
+ struct accept_filter_arg afa;
memset(&afa, 0, sizeof(afa));
strcpy(afa.af_name, "httpready");
if (setsockopt(srv_socket->fd, SOL_SOCKET, SO_ACCEPTFILTER, &afa, sizeof(afa)) < 0) {
diff --git a/src/request.c b/src/request.c
index b586c06..c5762e4 100644
--- a/src/request.c
+++ b/src/request.c
@@ -86,10 +86,18 @@ static int request_check_hostname(server *srv, connection *con, buffer *host) {
if (host_len == 0) return -1;
/* if the hostname ends in a "." strip it */
- if (host->ptr[host_len-1] == '.') host_len -= 1;
+ if (host->ptr[host_len-1] == '.') {
+ /* shift port info one left */
+ if (NULL != colon) memmove(colon-1, colon, host->used - host_len);
+ else host->ptr[host_len-1] = '\0';
+ host_len -= 1;
+ host->used -= 1;
+ }
+
+ if (host_len == 0) return -1;
/* scan from the right and skip the \0 */
- for (i = host_len - 1; i + 1 > 0; i--) {
+ for (i = host_len; i-- > 0; ) {
const char c = host->ptr[i];
switch (stage) {
@@ -200,7 +208,7 @@ static int request_check_hostname(server *srv, connection *con, buffer *host) {
#define DUMP_HEADER
#endif
-int http_request_split_value(array *vals, buffer *b) {
+static int http_request_split_value(array *vals, buffer *b) {
char *s;
size_t i;
int state = 0;
@@ -262,7 +270,7 @@ int http_request_split_value(array *vals, buffer *b) {
return 0;
}
-int request_uri_is_valid_char(unsigned char c) {
+static int request_uri_is_valid_char(unsigned char c) {
if (c <= 32) return 0;
if (c == 127) return 0;
if (c == 255) return 0;
@@ -948,18 +956,8 @@ int http_request_parse(server *srv, connection *con) {
if (!con->request.http_if_none_match) {
con->request.http_if_none_match = ds->value->ptr;
} else {
- con->http_status = 400;
- con->keep_alive = 0;
-
- if (srv->srvconf.log_request_header_on_error) {
- log_error_write(srv, __FILE__, __LINE__, "s",
- "duplicate If-None-Match-header -> 400");
- log_error_write(srv, __FILE__, __LINE__, "Sb",
- "request-header:\n",
- con->request.request);
- }
- array_insert_unique(con->request.headers, (data_unset *)ds);
- return 0;
+ ds->free((data_unset*) ds);
+ ds = NULL;
}
} else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Range")))) {
if (!con->request.http_range) {
diff --git a/src/response.c b/src/response.c
index 785e442..ae9aeff 100644
--- a/src/response.c
+++ b/src/response.c
@@ -25,6 +25,7 @@
#include "plugin.h"
#include "sys-socket.h"
+#include "version.h"
int http_response_write_header(server *srv, connection *con) {
buffer *b;
@@ -43,6 +44,11 @@ int http_response_write_header(server *srv, connection *con) {
buffer_append_string_len(b, CONST_STR_LEN(" "));
buffer_append_string(b, get_http_status_name(con->http_status));
+ /* disable keep-alive if requested */
+ if (con->request_count > con->conf.max_keep_alive_requests) {
+ con->keep_alive = 0;
+ }
+
if (con->request.http_version != HTTP_VERSION_1_1 || con->keep_alive == 0) {
if (con->keep_alive) {
response_header_overwrite(srv, con, CONST_STR_LEN("Connection"), CONST_STR_LEN("keep-alive"));
@@ -104,7 +110,7 @@ int http_response_write_header(server *srv, connection *con) {
if (!have_server) {
if (buffer_is_empty(con->conf.server_tag)) {
- buffer_append_string_len(b, CONST_STR_LEN("\r\nServer: " PACKAGE_NAME "/" PACKAGE_VERSION));
+ buffer_append_string_len(b, CONST_STR_LEN("\r\nServer: " PACKAGE_DESC));
} else if (con->conf.server_tag->used > 1) {
buffer_append_string_len(b, CONST_STR_LEN("\r\nServer: "));
buffer_append_string_encoded(b, CONST_BUF_LEN(con->conf.server_tag), ENCODING_HTTP_HEADER);
@@ -226,12 +232,6 @@ handler_t http_response_prepare(server *srv, connection *con) {
log_error_write(srv, __FILE__, __LINE__, "sb", "URI-query : ", con->uri.query);
}
- /* disable keep-alive if requested */
-
- if (con->request_count > con->conf.max_keep_alive_requests) {
- con->keep_alive = 0;
- }
-
/**
*
diff --git a/src/server.c b/src/server.c
index ee56b66..d5066ea 100644
--- a/src/server.c
+++ b/src/server.c
@@ -29,6 +29,7 @@
#include "plugin.h"
#include "joblist.h"
#include "network_backends.h"
+#include "version.h"
#ifdef HAVE_GETOPT_H
#include <getopt.h>
@@ -64,6 +65,17 @@
/* #define USE_ALARM */
#endif
+#ifdef HAVE_GETUID
+# ifndef HAVE_ISSETUGID
+
+static int l_issetugid() {
+ return (geteuid() != getuid() || getegid() != getgid());
+}
+
+# define issetugid l_issetugid
+# endif
+#endif
+
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;
@@ -157,6 +169,7 @@ static void daemonize(void) {
static server *server_init(void) {
int i;
+ FILE *frandom = NULL;
server *srv = calloc(1, sizeof(*srv));
assert(srv);
@@ -197,6 +210,19 @@ static server *server_init(void) {
srv->mtime_cache[i].str = buffer_init();
}
+ if ((NULL != (frandom = fopen("/dev/urandom", "rb")) || NULL != (frandom = fopen("/dev/random", "rb")))
+ && 1 == fread(srv->entropy, sizeof(srv->entropy), 1, frandom)) {
+ srand(*(unsigned int*)srv->entropy);
+ srv->is_real_entropy = 1;
+ } else {
+ unsigned int j;
+ srand(time(NULL) ^ getpid());
+ srv->is_real_entropy = 0;
+ for (j = 0; j < sizeof(srv->entropy); j++)
+ srv->entropy[j] = rand();
+ }
+ if (frandom) fclose(frandom);
+
srv->cur_ts = time(NULL);
srv->startup_ts = srv->cur_ts;
@@ -325,7 +351,7 @@ static void show_version (void) {
#else
# define TEXT_SSL
#endif
- char *b = PACKAGE_NAME "-" PACKAGE_VERSION TEXT_SSL \
+ char *b = PACKAGE_DESC TEXT_SSL \
" - a light and fast webserver\n" \
"Build-Date: " __DATE__ " " __TIME__ "\n";
;
@@ -462,7 +488,7 @@ static void show_help (void) {
#else
# define TEXT_SSL
#endif
- char *b = PACKAGE_NAME "-" PACKAGE_VERSION TEXT_SSL " ("__DATE__ " " __TIME__ ")" \
+ char *b = PACKAGE_DESC TEXT_SSL " ("__DATE__ " " __TIME__ ")" \
" - a light and fast webserver\n" \
"usage:\n" \
" -f <name> filename of the config-file\n" \
@@ -589,7 +615,7 @@ int main (int argc, char **argv) {
/* UID handling */
#ifdef HAVE_GETUID
- if (!i_am_root && (geteuid() == 0 || getegid() == 0)) {
+ if (!i_am_root && issetugid()) {
/* we are setuid-root */
log_error_write(srv, __FILE__, __LINE__, "s",
diff --git a/src/settings.h b/src/settings.h
index 349fc20..8d74c4a 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -13,6 +13,7 @@
* 64kB (no real reason, just a guess)
*/
#define BUFFER_MAX_REUSE_SIZE (4 * 1024)
+#define MAX_READ_LIMIT (4*1024*1024)
/**
* max size of the HTTP request header
diff --git a/src/spawn-fcgi.c b/src/spawn-fcgi.c
deleted file mode 100644
index a570e16..0000000
--- a/src/spawn-fcgi.c
+++ /dev/null
@@ -1,481 +0,0 @@
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/stat.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-
-#ifdef HAVE_PWD_H
-#include <grp.h>
-#include <pwd.h>
-#endif
-
-#ifdef HAVE_GETOPT_H
-#include <getopt.h>
-#endif
-
-#define FCGI_LISTENSOCK_FILENO 0
-
-#include "sys-socket.h"
-
-#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h>
-#endif
-
-/* for solaris 2.5 and netbsd 1.3.x */
-#ifndef HAVE_SOCKLEN_T
-typedef int socklen_t;
-#endif
-
-#ifdef HAVE_SYS_UN_H
-int fcgi_spawn_connection(char *appPath, char **appArgv, char *addr, unsigned short port, const char *unixsocket, int fork_count, int child_count, int pid_fd, int nofork) {
- int fcgi_fd;
- int socket_type, status, rc = 0;
- struct timeval tv = { 0, 100 * 1000 };
-
- struct sockaddr_un fcgi_addr_un;
- struct sockaddr_in fcgi_addr_in;
- struct sockaddr *fcgi_addr;
-
- socklen_t servlen;
-
- if (child_count < 2) {
- child_count = 5;
- }
-
- if (child_count > 256) {
- child_count = 256;
- }
-
-
- if (unixsocket) {
- memset(&fcgi_addr_un, 0, sizeof(fcgi_addr_un));
-
- fcgi_addr_un.sun_family = AF_UNIX;
- strcpy(fcgi_addr_un.sun_path, unixsocket);
-
-#ifdef SUN_LEN
- servlen = SUN_LEN(&fcgi_addr_un);
-#else
- /* stevens says: */
- servlen = strlen(fcgi_addr_un.sun_path) + sizeof(fcgi_addr_un.sun_family);
-#endif
- socket_type = AF_UNIX;
- fcgi_addr = (struct sockaddr *) &fcgi_addr_un;
- } else {
- memset(&fcgi_addr_in, 0, sizeof(fcgi_addr_in));
- fcgi_addr_in.sin_family = AF_INET;
- if (addr != NULL) {
- fcgi_addr_in.sin_addr.s_addr = inet_addr(addr);
- } else {
- fcgi_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
- }
- fcgi_addr_in.sin_port = htons(port);
- servlen = sizeof(fcgi_addr_in);
-
- socket_type = AF_INET;
- fcgi_addr = (struct sockaddr *) &fcgi_addr_in;
- }
-
- if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
- fprintf(stderr, "%s.%d\n",
- __FILE__, __LINE__);
- return -1;
- }
-
- if (-1 == connect(fcgi_fd, fcgi_addr, servlen)) {
- /* server is not up, spawn in */
- pid_t child;
- int val;
-
- if (unixsocket) unlink(unixsocket);
-
- close(fcgi_fd);
-
- /* reopen socket */
- if (-1 == (fcgi_fd = socket(socket_type, SOCK_STREAM, 0))) {
- fprintf(stderr, "%s.%d\n",
- __FILE__, __LINE__);
- return -1;
- }
-
- val = 1;
- if (setsockopt(fcgi_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) {
- fprintf(stderr, "%s.%d\n",
- __FILE__, __LINE__);
- return -1;
- }
-
- /* create socket */
- if (-1 == bind(fcgi_fd, fcgi_addr, servlen)) {
- fprintf(stderr, "%s.%d: bind failed: %s\n",
- __FILE__, __LINE__,
- strerror(errno));
- return -1;
- }
-
- if (-1 == listen(fcgi_fd, 1024)) {
- fprintf(stderr, "%s.%d: fd = -1\n",
- __FILE__, __LINE__);
- return -1;
- }
-
- while (fork_count-- > 0) {
-
- if (!nofork) {
- child = fork();
- } else {
- child = 0;
- }
-
- switch (child) {
- case 0: {
- char cgi_childs[64];
- int max_fd = 0;
-
- int i = 0;
-
- /* loose control terminal */
- setsid();
-
- /* is safe as we limit to 256 childs */
- sprintf(cgi_childs, "PHP_FCGI_CHILDREN=%d", child_count);
-
- if(fcgi_fd != FCGI_LISTENSOCK_FILENO) {
- close(FCGI_LISTENSOCK_FILENO);
- dup2(fcgi_fd, FCGI_LISTENSOCK_FILENO);
- close(fcgi_fd);
- }
-
- max_fd = open("/dev/null", O_RDWR);
- close(STDERR_FILENO);
- dup2(max_fd, STDERR_FILENO);
- close(max_fd);
-
- max_fd = open("/dev/null", O_RDWR);
- close(STDOUT_FILENO);
- dup2(max_fd, STDOUT_FILENO);
- close(max_fd);
-
- /* we don't need the client socket */
- for (i = 3; i < max_fd; i++) {
- if (i != FCGI_LISTENSOCK_FILENO) close(i);
- }
-
- /* create environment */
-
- putenv(cgi_childs);
-
- /* fork and replace shell */
- if (appArgv) {
- execv(appArgv[0], appArgv);
-
- } else {
- char *b = malloc(strlen("exec ") + strlen(appPath) + 1);
- strcpy(b, "exec ");
- strcat(b, appPath);
-
- /* exec the cgi */
- execl("/bin/sh", "sh", "-c", b, (char *)NULL);
- }
-
- exit(errno);
-
- break;
- }
- case -1:
- /* error */
- break;
- default:
- /* father */
-
- /* wait */
- select(0, NULL, NULL, NULL, &tv);
-
- switch (waitpid(child, &status, WNOHANG)) {
- case 0:
- fprintf(stdout, "%s.%d: child spawned successfully: PID: %d\n",
- __FILE__, __LINE__,
- child);
-
- /* write pid file */
- if (pid_fd != -1) {
- /* assume a 32bit pid_t */
- char pidbuf[12];
-
- snprintf(pidbuf, sizeof(pidbuf) - 1, "%d", child);
-
- write(pid_fd, pidbuf, strlen(pidbuf));
- /* avoid eol for the last one */
- if (fork_count != 0) {
- write(pid_fd, "\n", 1);
- }
- }
-
- break;
- case -1:
- break;
- default:
- if (WIFEXITED(status)) {
- fprintf(stderr, "%s.%d: child exited with: %d\n",
- __FILE__, __LINE__, WEXITSTATUS(status));
- rc = WEXITSTATUS(status);
- } else if (WIFSIGNALED(status)) {
- fprintf(stderr, "%s.%d: child signaled: %d\n",
- __FILE__, __LINE__,
- WTERMSIG(status));
- rc = 1;
- } else {
- fprintf(stderr, "%s.%d: child died somehow: %d\n",
- __FILE__, __LINE__,
- status);
- rc = status;
- }
- }
-
- break;
- }
- }
- close(pid_fd);
- pid_fd = -1;
- } else {
- fprintf(stderr, "%s.%d: socket is already used, can't spawn\n",
- __FILE__, __LINE__);
- return -1;
- }
-
- close(fcgi_fd);
-
- return rc;
-}
-
-
-void show_version () {
- char *b = "spawn-fcgi" "-" PACKAGE_VERSION \
-" - spawns fastcgi processes\n"
-;
- write(1, b, strlen(b));
-}
-
-void show_help () {
- char *b = \
-"Usage: spawn-fcgi [options] -- <fcgiapp> [fcgi app arguments]\n" \
-"\n" \
-"spawn-fcgi v" PACKAGE_VERSION " - spawns fastcgi processes\n" \
-"\n" \
-"Options:\n" \
-" -f <fcgiapp> filename of the fcgi-application\n" \
-" -a <addr> bind to ip address\n" \
-" -p <port> bind to tcp-port\n" \
-" -s <path> bind to unix-domain socket\n" \
-" -C <childs> (PHP only) numbers of childs to spawn (default 5)\n" \
-" -F <childs> numbers of childs to fork (default 1)\n" \
-" -P <path> name of PID-file for spawed process\n" \
-" -n no fork (for daemontools)\n" \
-" -v show version\n" \
-" -h show this help\n" \
-"(root only)\n" \
-" -c <dir> chroot to directory\n" \
-" -u <user> change to user-id\n" \
-" -g <group> change to group-id\n" \
-;
- write(1, b, strlen(b));
-}
-
-
-int main(int argc, char **argv) {
- char *fcgi_app = NULL, *changeroot = NULL, *username = NULL,
- *groupname = NULL, *unixsocket = NULL, *pid_file = NULL,
- *addr = NULL;
- char **fcgi_app_argv = { NULL };
- unsigned short port = 0;
- int child_count = 5;
- int fork_count = 1;
- int i_am_root, o;
- int pid_fd = -1;
- int nofork = 0;
- struct sockaddr_un un;
-
- i_am_root = (getuid() == 0);
-
- while (-1 != (o = getopt(argc, argv, "c:f:g:hna:p:u:vC:F:s:P:"))) {
- switch(o) {
- case 'f': fcgi_app = optarg; break;
- case 'a': addr = optarg;/* ip addr */ break;
- case 'p': port = strtol(optarg, NULL, 10);/* port */ break;
- case 'C': child_count = strtol(optarg, NULL, 10);/* */ break;
- case 'F': fork_count = strtol(optarg, NULL, 10);/* */ break;
- case 's': unixsocket = optarg; /* unix-domain socket */ break;
- case 'c': if (i_am_root) { changeroot = optarg; }/* chroot() */ break;
- case 'u': if (i_am_root) { username = optarg; } /* set user */ break;
- case 'g': if (i_am_root) { groupname = optarg; } /* set group */ break;
- case 'n': nofork = 1; break;
- case 'P': pid_file = optarg; /* PID file */ break;
- case 'v': show_version(); return 0;
- case 'h': show_help(); return 0;
- default:
- show_help();
- return -1;
- }
- }
-
- if (optind < argc) {
- fcgi_app_argv = &argv[optind];
- }
-
- if ((fcgi_app == NULL && fcgi_app_argv == NULL) || (port == 0 && unixsocket == NULL)) {
- show_help();
- return -1;
- }
-
- if (unixsocket && port) {
- fprintf(stderr, "%s.%d: %s\n",
- __FILE__, __LINE__,
- "either a unix domain socket or a tcp-port, but not both\n");
-
- return -1;
- }
-
- if (unixsocket && strlen(unixsocket) > sizeof(un.sun_path) - 1) {
- fprintf(stderr, "%s.%d: %s\n",
- __FILE__, __LINE__,
- "path of the unix socket is too long\n");
-
- return -1;
- }
-
- /* UID handling */
- if (!i_am_root && (geteuid() == 0 || getegid() == 0)) {
- /* we are setuid-root */
-
- fprintf(stderr, "%s.%d: %s\n",
- __FILE__, __LINE__,
- "Are you nuts ? Don't apply a SUID bit to this binary\n");
-
- return -1;
- }
-
- if (pid_file &&
- (-1 == (pid_fd = open(pid_file, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)))) {
- struct stat st;
- if (errno != EEXIST) {
- fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n",
- __FILE__, __LINE__,
- pid_file, strerror(errno));
-
- return -1;
- }
-
- /* ok, file exists */
-
- if (0 != stat(pid_file, &st)) {
- fprintf(stderr, "%s.%d: stating pid-file '%s' failed: %s\n",
- __FILE__, __LINE__,
- pid_file, strerror(errno));
-
- return -1;
- }
-
- /* is it a regular file ? */
-
- if (!S_ISREG(st.st_mode)) {
- fprintf(stderr, "%s.%d: pid-file exists and isn't regular file: '%s'\n",
- __FILE__, __LINE__,
- pid_file);
-
- return -1;
- }
-
- if (-1 == (pid_fd = open(pid_file, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
- fprintf(stderr, "%s.%d: opening pid-file '%s' failed: %s\n",
- __FILE__, __LINE__,
- pid_file, strerror(errno));
-
- return -1;
- }
- }
-
- if (i_am_root) {
- struct group *grp = NULL;
- struct passwd *pwd = NULL;
-
- /* set user and group */
-
- if (username) {
- if (NULL == (pwd = getpwnam(username))) {
- fprintf(stderr, "%s.%d: %s, %s\n",
- __FILE__, __LINE__,
- "can't find username", username);
- return -1;
- }
-
- if (pwd->pw_uid == 0) {
- fprintf(stderr, "%s.%d: %s\n",
- __FILE__, __LINE__,
- "I will not set uid to 0\n");
- return -1;
- }
- }
-
- if (groupname) {
- if (NULL == (grp = getgrnam(groupname))) {
- fprintf(stderr, "%s.%d: %s %s\n",
- __FILE__, __LINE__,
- "can't find groupname",
- groupname);
- return -1;
- }
- if (grp->gr_gid == 0) {
- fprintf(stderr, "%s.%d: %s\n",
- __FILE__, __LINE__,
- "I will not set gid to 0\n");
- return -1;
- }
-
- /* do the change before we do the chroot() */
- setgid(grp->gr_gid);
- setgroups(0, NULL);
-
- if (username) {
- initgroups(username, grp->gr_gid);
- }
-
- }
-
- if (changeroot) {
- if (-1 == chroot(changeroot)) {
- fprintf(stderr, "%s.%d: %s %s\n",
- __FILE__, __LINE__,
- "chroot failed: ", strerror(errno));
- return -1;
- }
- if (-1 == chdir("/")) {
- fprintf(stderr, "%s.%d: %s %s\n",
- __FILE__, __LINE__,
- "chdir failed: ", strerror(errno));
- return -1;
- }
- }
-
- /* drop root privs */
- if (username) {
- setuid(pwd->pw_uid);
- }
- }
-
- return fcgi_spawn_connection(fcgi_app, fcgi_app_argv, addr, port, unixsocket, fork_count, child_count, pid_fd, nofork);
-}
-#else
-int main() {
- return -1;
-}
-#endif
diff --git a/src/splaytree.c b/src/splaytree.c
index 5d6a2b4..68b0b73 100644
--- a/src/splaytree.c
+++ b/src/splaytree.c
@@ -187,7 +187,8 @@ splay_tree * splaytree_delete(splay_tree *t, int i) {
}
}
-splay_tree *find_rank(int r, splay_tree *t) {
+#if 0
+static splay_tree *find_rank(int r, splay_tree *t) {
/* Returns a pointer to the node in the tree with the given rank. */
/* Returns NULL if there is no such node. */
/* Does not change the tree. To guarantee logarithmic behavior, */
@@ -206,5 +207,4 @@ splay_tree *find_rank(int r, splay_tree *t) {
}
}
}
-
-
+#endif
diff --git a/src/stat_cache.c b/src/stat_cache.c
index fa94eed..2657143 100644
--- a/src/stat_cache.c
+++ b/src/stat_cache.c
@@ -489,6 +489,12 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
if (S_ISREG(st.st_mode)) {
+ /* fix broken stat/open for symlinks to reg files with appended slash on freebsd,osx */
+ if (name->ptr[name->used-2] == '/') {
+ errno = ENOTDIR;
+ return HANDLER_ERROR;
+ }
+
/* try to open the file to check if we can read it */
if (-1 == (fd = open(name->ptr, O_RDONLY))) {
return HANDLER_ERROR;
@@ -595,29 +601,31 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
if (S_ISREG(st.st_mode)) {
/* determine mimetype */
buffer_reset(sce->content_type);
+#ifdef HAVE_XATTR
+ if (con->conf.use_xattr) {
+ stat_cache_attr_get(sce->content_type, name->ptr);
+ }
+#endif
+ /* xattr did not set a content-type. ask the config */
+ if (buffer_is_empty(sce->content_type)) {
+ for (k = 0; k < con->conf.mimetypes->used; k++) {
+ data_string *ds = (data_string *)con->conf.mimetypes->data[k];
+ buffer *type = ds->key;
- for (k = 0; k < con->conf.mimetypes->used; k++) {
- data_string *ds = (data_string *)con->conf.mimetypes->data[k];
- buffer *type = ds->key;
-
- if (type->used == 0) continue;
+ if (type->used == 0) continue;
- /* check if the right side is the same */
- if (type->used > name->used) continue;
+ /* check if the right side is the same */
+ if (type->used > name->used) continue;
- if (0 == strncasecmp(name->ptr + name->used - type->used, type->ptr, type->used - 1)) {
- buffer_copy_string_buffer(sce->content_type, ds->value);
- break;
+ if (0 == strncasecmp(name->ptr + name->used - type->used, type->ptr, type->used - 1)) {
+ buffer_copy_string_buffer(sce->content_type, ds->value);
+ break;
+ }
}
}
- etag_create(sce->etag, &(sce->st), con->etag_flags);
-#ifdef HAVE_XATTR
- if (con->conf.use_xattr && buffer_is_empty(sce->content_type)) {
- stat_cache_attr_get(sce->content_type, name->ptr);
- }
-#endif
+ etag_create(sce->etag, &(sce->st), con->etag_flags);
} else if (S_ISDIR(st.st_mode)) {
- etag_create(sce->etag, &(sce->st), con->etag_flags);
+ etag_create(sce->etag, &(sce->st), con->etag_flags);
}
#ifdef HAVE_FAM_H
diff --git a/src/version.h b/src/version.h
new file mode 100644
index 0000000..f8eea22
--- /dev/null
+++ b/src/version.h
@@ -0,0 +1,12 @@
+#ifndef _VERSION_H_
+#define _VERSION_H_
+
+#ifdef HAVE_VERSION_H
+#include "versionstamp.h"
+#else
+#define REPO_VERSION ""
+#endif
+
+#define PACKAGE_DESC PACKAGE_NAME "/" PACKAGE_VERSION REPO_VERSION
+
+#endif