diff options
Diffstat (limited to 'src')
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); @@ -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) { @@ -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; @@ -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); @@ -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 |
