diff -u -r -N squid-3.1.7/bootstrap.sh squid-3.1.8/bootstrap.sh
--- squid-3.1.7/bootstrap.sh 2010-08-24 17:41:26.000000000 +1200
+++ squid-3.1.8/bootstrap.sh 2010-09-04 15:25:58.000000000 +1200
@@ -7,9 +7,9 @@
# Autotool versions preferred. To override either edit the script
# to match the versions you want to use, or set the variables on
# the command line like "env acver=.. amver=... ./bootstrap.sh"
-acversions="${acver:-2.63 2.62 2.61}"
+acversions="${acver:-2.64 2.63 2.62 2.61}"
amversions="${amver:-1.11 1.10 1.9}"
-ltversions="${ltver:-2.2 1.5 1.4}"
+ltversions="${ltver:-2.2}"
check_version()
{
@@ -113,19 +113,6 @@
chmod u+w $makefile
mv $makefile.new $makefile
chmod u-w $makefile
-
- # Libtool 2.2.6b we bundle is slightly broken with non-portable dependencies
- # HACK: Make it backward-compatible by linking the bundled headers.
- for f in ltdl.h libltdl/lt_error.h libltdl/lt_system.h libltdl/lt_dlloader.h libltdl/slist.h; do
- echo "Fixing $f ..."
- sed 's//\"libltdl\/lt_system.h\"/g' $src/$f |
- sed 's//\"libltdl\/lt__glibc.h\"/g' |
- sed 's//\"libltdl\/lt_error.h\"/g' |
- sed 's//\"libltdl\/lt_dlloader.h\"/g' > $src/$f.new;
- chmod u+w $src/$f
- mv $src/$f.new $src/$f
- chmod u-w $src/$f
- done
fi
}
diff -u -r -N squid-3.1.7/ChangeLog squid-3.1.8/ChangeLog
--- squid-3.1.7/ChangeLog 2010-08-24 17:41:25.000000000 +1200
+++ squid-3.1.8/ChangeLog 2010-09-04 15:25:57.000000000 +1200
@@ -1,3 +1,16 @@
+Changes to squid-3.1.8 (04 Sep 2010):
+
+ - Bug 3033: incorrect information regarding TOS
+ - Bug 3020: Segmentation fault: nameservers[vc->ns].vc = NULL
+ - Bug 3005,2972: Locate LTDL headers correctly (again)
+ - Bug 2872: leaking file descriptors
+ - Bug 2583: pure virtual method called
+ - Hardened DNS client against packet queue attacks
+ - Hardened HTTP request-line parser
+ - Several HTTP/1.1 support improvements
+ - Improved cross-compile support
+ - .. and several internal pointer safety fixes
+
Changes to squid-3.1.7 (23 Aug 2010):
- Regression Bug 3021: Large DNS reply causes crash
diff -u -r -N squid-3.1.7/compat/Makefile.in squid-3.1.8/compat/Makefile.in
--- squid-3.1.7/compat/Makefile.in 2010-08-24 17:42:19.000000000 +1200
+++ squid-3.1.8/compat/Makefile.in 2010-09-04 15:26:19.000000000 +1200
@@ -40,6 +40,7 @@
$(top_srcdir)/src/Common.am
check_PROGRAMS = testPreCompiler$(EXEEXT)
TESTS = testPreCompiler$(EXEEXT) testHeaders
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
subdir = compat
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
@@ -287,13 +288,8 @@
AM_CFLAGS = $(SQUID_CFLAGS)
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES = testHeaders
-INCLUDES = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/include \
- -I$(top_srcdir)/src \
- -I$(top_builddir)/include \
- $(SQUID_CPPUNIT_INC)
-
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1)
# Ideally this would be 100% inline functions and macro wrappers.
diff -u -r -N squid-3.1.7/configure squid-3.1.8/configure
--- squid-3.1.7/configure 2010-08-24 17:43:37.000000000 +1200
+++ squid-3.1.8/configure 2010-09-04 15:26:52.000000000 +1200
@@ -1,7 +1,7 @@
#! /bin/sh
# From configure.in Revision.
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.62 for Squid Web Proxy 3.1.7.
+# Generated by GNU Autoconf 2.62 for Squid Web Proxy 3.1.8.
#
# Report bugs to .
#
@@ -750,8 +750,8 @@
# Identity of this package.
PACKAGE_NAME='Squid Web Proxy'
PACKAGE_TARNAME='squid'
-PACKAGE_VERSION='3.1.7'
-PACKAGE_STRING='Squid Web Proxy 3.1.7'
+PACKAGE_VERSION='3.1.8'
+PACKAGE_STRING='Squid Web Proxy 3.1.8'
PACKAGE_BUGREPORT='http://www.squid-cache.org/bugs/'
ac_unique_file="src/main.cc"
@@ -1712,7 +1712,7 @@
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures Squid Web Proxy 3.1.7 to adapt to many kinds of systems.
+\`configure' configures Squid Web Proxy 3.1.8 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1782,7 +1782,7 @@
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of Squid Web Proxy 3.1.7:";;
+ short | recursive ) echo "Configuration of Squid Web Proxy 3.1.8:";;
esac
cat <<\_ACEOF
@@ -2109,7 +2109,7 @@
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-Squid Web Proxy configure 3.1.7
+Squid Web Proxy configure 3.1.8
generated by GNU Autoconf 2.62
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -2123,7 +2123,7 @@
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by Squid Web Proxy $as_me 3.1.7, which was
+It was created by Squid Web Proxy $as_me 3.1.8, which was
generated by GNU Autoconf 2.62. Invocation command line was
$ $0 $@
@@ -2841,7 +2841,7 @@
# Define the identity of the package.
PACKAGE='squid'
- VERSION='3.1.7'
+ VERSION='3.1.8'
cat >>confdefs.h <<_ACEOF
@@ -19451,11 +19451,7 @@
if test "$cross_compiling" = yes; then
- { { $as_echo "$as_me:$LINENO: error: cannot run test program while cross compiling
-See \`config.log' for more details." >&5
-$as_echo "$as_me: error: cannot run test program while cross compiling
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
+ :
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
@@ -22760,11 +22756,7 @@
$as_echo_n "(cached) " >&6
else
if test "$cross_compiling" = yes; then
- { { $as_echo "$as_me:$LINENO: error: cannot run test program while cross compiling
-See \`config.log' for more details." >&5
-$as_echo "$as_me: error: cannot run test program while cross compiling
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
+ :
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
@@ -39923,6 +39915,362 @@
fi
+#need the define for overflow checks
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:$LINENO: checking size of off_t" >&5
+$as_echo_n "checking size of off_t... " >&6; }
+if test "${ac_cv_sizeof_off_t+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then
+ # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long int) (sizeof (off_t))) >= 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long int) (sizeof (off_t))) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_hi=$ac_mid; break
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_lo=`expr $ac_mid + 1`
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long int) (sizeof (off_t))) < 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long int) (sizeof (off_t))) >= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_lo=$ac_mid; break
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_hi=`expr '(' $ac_mid ')' - 1`
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid`
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_lo= ac_hi=
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long int) (sizeof (off_t))) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_hi=$ac_mid
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_off_t=$ac_lo;;
+'') if test "$ac_cv_type_off_t" = yes; then
+ { { $as_echo "$as_me:$LINENO: error: cannot compute sizeof (off_t)
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: cannot compute sizeof (off_t)
+See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }
+ else
+ ac_cv_sizeof_off_t=0
+ fi ;;
+esac
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+static long int longval () { return (long int) (sizeof (off_t)); }
+static unsigned long int ulongval () { return (long int) (sizeof (off_t)); }
+#include
+#include
+int
+main ()
+{
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ return 1;
+ if (((long int) (sizeof (off_t))) < 0)
+ {
+ long int i = longval ();
+ if (i != ((long int) (sizeof (off_t))))
+ return 1;
+ fprintf (f, "%ld", i);
+ }
+ else
+ {
+ unsigned long int i = ulongval ();
+ if (i != ((long int) (sizeof (off_t))))
+ return 1;
+ fprintf (f, "%lu", i);
+ }
+ /* Do not output a trailing newline, as this causes \r\n confusion
+ on some platforms. */
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_sizeof_off_t=`cat conftest.val`
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+if test "$ac_cv_type_off_t" = yes; then
+ { { $as_echo "$as_me:$LINENO: error: cannot compute sizeof (off_t)
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: cannot compute sizeof (off_t)
+See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }
+ else
+ ac_cv_sizeof_off_t=0
+ fi
+fi
+rm -rf conftest.dSYM
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.val
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_sizeof_off_t" >&5
+$as_echo "$ac_cv_sizeof_off_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_OFF_T $ac_cv_sizeof_off_t
+_ACEOF
+
+
{ $as_echo "$as_me:$LINENO: checking for pad128_t" >&5
$as_echo_n "checking for pad128_t... " >&6; }
@@ -46229,11 +46577,7 @@
$as_echo_n "(cached) " >&6
else
if test "$cross_compiling" = yes; then
- { { $as_echo "$as_me:$LINENO: error: cannot run test program while cross compiling
-See \`config.log' for more details." >&5
-$as_echo "$as_me: error: cannot run test program while cross compiling
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
+ :
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
@@ -46306,11 +46650,7 @@
$as_echo_n "(cached) " >&6
else
if test "$cross_compiling" = yes; then
- { { $as_echo "$as_me:$LINENO: error: cannot run test program while cross compiling
-See \`config.log' for more details." >&5
-$as_echo "$as_me: error: cannot run test program while cross compiling
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
+ :
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
@@ -46394,11 +46734,7 @@
$as_echo_n "(cached) " >&6
else
if test "$cross_compiling" = yes; then
- { { $as_echo "$as_me:$LINENO: error: cannot run test program while cross compiling
-See \`config.log' for more details." >&5
-$as_echo "$as_me: error: cannot run test program while cross compiling
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
+ :
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
@@ -46475,11 +46811,7 @@
$as_echo_n "(cached) " >&6
else
if test "$cross_compiling" = yes; then
- { { $as_echo "$as_me:$LINENO: error: cannot run test program while cross compiling
-See \`config.log' for more details." >&5
-$as_echo "$as_me: error: cannot run test program while cross compiling
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
+ :
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
@@ -48878,7 +49210,7 @@
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by Squid Web Proxy $as_me 3.1.7, which was
+This file was extended by Squid Web Proxy $as_me 3.1.8, which was
generated by GNU Autoconf 2.62. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -48931,7 +49263,7 @@
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\
-Squid Web Proxy config.status 3.1.7
+Squid Web Proxy config.status 3.1.8
configured by $0, generated by GNU Autoconf 2.62,
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
diff -u -r -N squid-3.1.7/configure.in squid-3.1.8/configure.in
--- squid-3.1.7/configure.in 2010-08-24 17:43:36.000000000 +1200
+++ squid-3.1.8/configure.in 2010-09-04 15:26:52.000000000 +1200
@@ -2,7 +2,7 @@
dnl
dnl $Id$
dnl
-AC_INIT([Squid Web Proxy],[3.1.7],[http://www.squid-cache.org/bugs/],[squid])
+AC_INIT([Squid Web Proxy],[3.1.8],[http://www.squid-cache.org/bugs/],[squid])
AC_PREREQ(2.61)
AC_CONFIG_HEADERS([include/autoconf.h])
AC_CONFIG_AUX_DIR(cfgaux)
@@ -366,7 +366,7 @@
dnl Nasty hack to get autoconf 2.64 on Linux to run.
dnl all other uses of RUN_IFELSE are wrapped inside CACHE_CHECK which breaks on 2.64
-AC_RUN_IFELSE([AC_LANG_SOURCE([[ int main(int argc, char **argv) { return 0; } ]])],[],[],[])
+AC_RUN_IFELSE([AC_LANG_SOURCE([[ int main(int argc, char **argv) { return 0; } ]])],[],[],[:])
dnl This is a developer only option.. developers know how to set defines
dnl
@@ -1331,7 +1331,7 @@
}
return 0;
}
- ]])],[ac_cv_epoll_works=yes],[ac_cv_epoll_works=no],[]))
+ ]])],[ac_cv_epoll_works=yes],[ac_cv_epoll_works=no],[:]))
fi
if test "$force_epoll" = "yes" && test "$ac_cv_epoll_works" = "no" ; then
@@ -2481,6 +2481,8 @@
AC_CHECK_SIZEOF(uint64_t,,SQUID_DEFAULT_SIZEOF_INCLUDES)
AC_DEFINE(HAVE_UINT64_T,1,[uint64_t is defined in system headers])
],,SQUID_DEFAULT_INCLUDES)
+#need the define for overflow checks
+AC_CHECK_SIZEOF(off_t)
dnl On Solaris 9 x86, gcc may includes a "fixed" set of old system include files
dnl that is incompatible with the updated Solaris header files.
@@ -3075,7 +3077,7 @@
}
return 0;
}
- ]])],[ac_cv_func_setresuid="yes"],[ac_cv_func_setresuid="no"],[])
+ ]])],[ac_cv_func_setresuid="yes"],[ac_cv_func_setresuid="no"],[:])
)
if test "$ac_cv_func_setresuid" = "yes" ; then
AC_DEFINE(HAVE_SETRESUID,1,[Yay! Another Linux brokenness. Its not good enough to know that setresuid() exists, because RedHat 5.0 declare setresuid() but doesn't implement it.])
@@ -3100,7 +3102,7 @@
strnstr(str, "fubar", size);
return 0;
}
- ]])],[ac_cv_func_strnstr="yes"],[ac_cv_func_strnstr="no"],[])
+ ]])],[ac_cv_func_strnstr="yes"],[ac_cv_func_strnstr="no"],[:])
)
if test "$ac_cv_func_strnstr" = "yes" ; then
AC_DEFINE(HAVE_STRNSTR,1,[Yay! We have a working strnstr!])
@@ -3125,7 +3127,7 @@
return 0;
}
int main(int argc, char **argv) { return f (0, 42); }
- ]])],[ac_cv_func_va_copy="yes"],[ac_cv_func_va_copy="no"],[])
+ ]])],[ac_cv_func_va_copy="yes"],[ac_cv_func_va_copy="no"],[:])
)
if test "$ac_cv_func_va_copy" = "yes" ; then
AC_DEFINE(HAVE_VA_COPY, 1, [If your system have va_copy])
@@ -3148,7 +3150,7 @@
return 0;
}
int main(int argc, char **argv) { return f (0, 42); }
- ]])],[ac_cv_func___va_copy="yes"],[ac_cv_func___va_copy="no"],[])
+ ]])],[ac_cv_func___va_copy="yes"],[ac_cv_func___va_copy="no"],[:])
)
if test "$ac_cv_func___va_copy" = "yes" ; then
AC_DEFINE(HAVE___VA_COPY, 1, [Some systems have __va_copy instead of va_copy])
diff -u -r -N squid-3.1.7/helpers/basic_auth/getpwnam/Makefile.in squid-3.1.8/helpers/basic_auth/getpwnam/Makefile.in
--- squid-3.1.7/helpers/basic_auth/getpwnam/Makefile.in 2010-08-24 17:42:23.000000000 +1200
+++ squid-3.1.8/helpers/basic_auth/getpwnam/Makefile.in 2010-09-04 15:26:21.000000000 +1200
@@ -44,6 +44,7 @@
$(top_srcdir)/src/Common.am
check_PROGRAMS =
TESTS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
libexec_PROGRAMS = getpwname_auth$(EXEEXT)
subdir = helpers/basic_auth/getpwnam
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -280,7 +281,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES =
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir)
getpwname_auth_SOURCES = getpwnam_auth.c
LDADD = \
$(top_builddir)/compat/libcompat.la \
diff -u -r -N squid-3.1.7/helpers/basic_auth/LDAP/Makefile.in squid-3.1.8/helpers/basic_auth/LDAP/Makefile.in
--- squid-3.1.7/helpers/basic_auth/LDAP/Makefile.in 2010-08-24 17:42:21.000000000 +1200
+++ squid-3.1.8/helpers/basic_auth/LDAP/Makefile.in 2010-09-04 15:26:20.000000000 +1200
@@ -44,6 +44,7 @@
$(top_srcdir)/src/Common.am
check_PROGRAMS =
TESTS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
libexec_PROGRAMS = squid_ldap_auth$(EXEEXT)
subdir = helpers/basic_auth/LDAP
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -284,7 +285,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES =
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir)
man_MANS = squid_ldap_auth.8
squid_ldap_auth_SOURCES = squid_ldap_auth.c
EXTRA_DIST = squid_ldap_auth.8 config.test
diff -u -r -N squid-3.1.7/helpers/basic_auth/MSNT/Makefile.in squid-3.1.8/helpers/basic_auth/MSNT/Makefile.in
--- squid-3.1.7/helpers/basic_auth/MSNT/Makefile.in 2010-08-24 17:42:21.000000000 +1200
+++ squid-3.1.8/helpers/basic_auth/MSNT/Makefile.in 2010-09-04 15:26:20.000000000 +1200
@@ -37,6 +37,7 @@
$(top_srcdir)/src/Common.am
check_PROGRAMS =
TESTS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
libexec_PROGRAMS = msnt_auth$(EXEEXT)
subdir = helpers/basic_auth/MSNT
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -285,7 +286,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES =
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir)
MSNTAUTH_CONF = $(sysconfdir)/msntauth.conf
msnt_auth_SOURCES = md4.c rfcnb-io.c rfcnb-util.c session.c msntauth.c \
msntauth.h smbdes.c smbencrypt.c smblib-util.c smblib.c \
diff -u -r -N squid-3.1.7/helpers/basic_auth/mswin_sspi/Makefile.in squid-3.1.8/helpers/basic_auth/mswin_sspi/Makefile.in
--- squid-3.1.7/helpers/basic_auth/mswin_sspi/Makefile.in 2010-08-24 17:42:24.000000000 +1200
+++ squid-3.1.8/helpers/basic_auth/mswin_sspi/Makefile.in 2010-09-04 15:26:21.000000000 +1200
@@ -44,6 +44,7 @@
$(top_srcdir)/src/Common.am
check_PROGRAMS =
TESTS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
libexec_PROGRAMS = mswin_auth$(EXEEXT)
subdir = helpers/basic_auth/mswin_sspi
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -280,7 +281,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES =
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir)
mswin_auth_SOURCES = mswin_auth.c valid.c valid.h
LDADD = \
$(top_builddir)/compat/libcompat.la \
diff -u -r -N squid-3.1.7/helpers/basic_auth/NCSA/Makefile.in squid-3.1.8/helpers/basic_auth/NCSA/Makefile.in
--- squid-3.1.7/helpers/basic_auth/NCSA/Makefile.in 2010-08-24 17:42:21.000000000 +1200
+++ squid-3.1.8/helpers/basic_auth/NCSA/Makefile.in 2010-09-04 15:26:20.000000000 +1200
@@ -44,6 +44,7 @@
$(top_srcdir)/src/Common.am
check_PROGRAMS =
TESTS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
libexec_PROGRAMS = ncsa_auth$(EXEEXT)
subdir = helpers/basic_auth/NCSA
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -284,7 +285,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES =
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir)
ncsa_auth_SOURCES = ncsa_auth.c crypt_md5.c crypt_md5.h
man_MANS = ncsa_auth.8
EXTRA_DIST = ncsa_auth.8 config.test
diff -u -r -N squid-3.1.7/helpers/basic_auth/PAM/Makefile.in squid-3.1.8/helpers/basic_auth/PAM/Makefile.in
--- squid-3.1.7/helpers/basic_auth/PAM/Makefile.in 2010-08-24 17:42:22.000000000 +1200
+++ squid-3.1.8/helpers/basic_auth/PAM/Makefile.in 2010-09-04 15:26:20.000000000 +1200
@@ -44,6 +44,7 @@
$(top_srcdir)/src/Common.am
check_PROGRAMS =
TESTS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
libexec_PROGRAMS = pam_auth$(EXEEXT)
subdir = helpers/basic_auth/PAM
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -283,7 +284,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES =
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir)
man_MANS = pam_auth.8
EXTRA_DIST = pam_auth.8 config.test
LDADD = \
diff -u -r -N squid-3.1.7/helpers/basic_auth/SASL/Makefile.in squid-3.1.8/helpers/basic_auth/SASL/Makefile.in
--- squid-3.1.7/helpers/basic_auth/SASL/Makefile.in 2010-08-24 17:42:22.000000000 +1200
+++ squid-3.1.8/helpers/basic_auth/SASL/Makefile.in 2010-09-04 15:26:21.000000000 +1200
@@ -44,6 +44,7 @@
$(top_srcdir)/src/Common.am
check_PROGRAMS =
TESTS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
libexec_PROGRAMS = sasl_auth$(EXEEXT)
subdir = helpers/basic_auth/SASL
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -280,7 +281,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES =
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir)
LDADD = \
$(top_builddir)/compat/libcompat.la \
-L$(top_builddir)/lib -lmiscutil \
diff -u -r -N squid-3.1.7/helpers/basic_auth/SMB/Makefile.in squid-3.1.8/helpers/basic_auth/SMB/Makefile.in
--- squid-3.1.7/helpers/basic_auth/SMB/Makefile.in 2010-08-24 17:42:23.000000000 +1200
+++ squid-3.1.8/helpers/basic_auth/SMB/Makefile.in 2010-09-04 15:26:21.000000000 +1200
@@ -45,6 +45,7 @@
$(top_srcdir)/src/Common.am ChangeLog
check_PROGRAMS =
TESTS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
libexec_PROGRAMS = smb_auth$(EXEEXT)
subdir = helpers/basic_auth/SMB
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -286,7 +287,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES =
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir)
# SAMBAPREFIX must point to the directory where Samba has been installed.
# By default, Samba is installed in /usr/local/samba. If you changed this
diff -u -r -N squid-3.1.7/helpers/basic_auth/squid_radius_auth/Makefile.in squid-3.1.8/helpers/basic_auth/squid_radius_auth/Makefile.in
--- squid-3.1.7/helpers/basic_auth/squid_radius_auth/Makefile.in 2010-08-24 17:42:24.000000000 +1200
+++ squid-3.1.8/helpers/basic_auth/squid_radius_auth/Makefile.in 2010-09-04 15:26:22.000000000 +1200
@@ -44,6 +44,7 @@
$(top_srcdir)/src/Common.am
check_PROGRAMS =
TESTS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
libexec_PROGRAMS = squid_radius_auth$(EXEEXT)
subdir = helpers/basic_auth/squid_radius_auth
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -284,7 +285,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES =
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir)
man_MANS = squid_radius_auth.8
EXTRA_DIST = squid_radius_auth.8 config.test
squid_radius_auth_SOURCES = \
diff -u -r -N squid-3.1.7/helpers/basic_auth/YP/Makefile.in squid-3.1.8/helpers/basic_auth/YP/Makefile.in
--- squid-3.1.7/helpers/basic_auth/YP/Makefile.in 2010-08-24 17:42:23.000000000 +1200
+++ squid-3.1.8/helpers/basic_auth/YP/Makefile.in 2010-09-04 15:26:21.000000000 +1200
@@ -43,6 +43,7 @@
$(top_srcdir)/src/Common.am
check_PROGRAMS =
TESTS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
libexec_PROGRAMS = yp_auth$(EXEEXT)
subdir = helpers/basic_auth/YP
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -279,7 +280,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES =
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir)
yp_auth_SOURCES = yp_auth.c nis_support.h nis_support.c
LDADD = \
$(top_builddir)/compat/libcompat.la \
diff -u -r -N squid-3.1.7/helpers/digest_auth/eDirectory/Makefile.in squid-3.1.8/helpers/digest_auth/eDirectory/Makefile.in
--- squid-3.1.7/helpers/digest_auth/eDirectory/Makefile.in 2010-08-24 17:42:24.000000000 +1200
+++ squid-3.1.8/helpers/digest_auth/eDirectory/Makefile.in 2010-09-04 15:26:22.000000000 +1200
@@ -44,6 +44,7 @@
$(top_srcdir)/src/Common.am
check_PROGRAMS =
TESTS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
libexec_PROGRAMS = digest_edir_auth$(EXEEXT)
subdir = helpers/digest_auth/eDirectory
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -283,7 +284,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES =
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir)
digest_edir_auth_SOURCES = digest_pw_auth.c \
digest_common.h \
ldap_backend.c \
diff -u -r -N squid-3.1.7/helpers/digest_auth/ldap/Makefile.in squid-3.1.8/helpers/digest_auth/ldap/Makefile.in
--- squid-3.1.7/helpers/digest_auth/ldap/Makefile.in 2010-08-24 17:42:24.000000000 +1200
+++ squid-3.1.8/helpers/digest_auth/ldap/Makefile.in 2010-09-04 15:26:22.000000000 +1200
@@ -44,6 +44,7 @@
$(top_srcdir)/src/Common.am
check_PROGRAMS =
TESTS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
libexec_PROGRAMS = digest_ldap_auth$(EXEEXT)
subdir = helpers/digest_auth/ldap
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -283,7 +284,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES =
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir)
digest_ldap_auth_SOURCES = digest_pw_auth.c \
digest_common.h \
ldap_backend.c \
diff -u -r -N squid-3.1.7/helpers/digest_auth/password/Makefile.in squid-3.1.8/helpers/digest_auth/password/Makefile.in
--- squid-3.1.7/helpers/digest_auth/password/Makefile.in 2010-08-24 17:42:25.000000000 +1200
+++ squid-3.1.8/helpers/digest_auth/password/Makefile.in 2010-09-04 15:26:22.000000000 +1200
@@ -44,6 +44,7 @@
$(top_srcdir)/src/Common.am
check_PROGRAMS =
TESTS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
libexec_PROGRAMS = digest_pw_auth$(EXEEXT)
subdir = helpers/digest_auth/password
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -282,7 +283,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES =
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir)
digest_pw_auth_SOURCES = digest_pw_auth.c \
digest_common.h \
text_backend.c \
diff -u -r -N squid-3.1.7/helpers/external_acl/ip_user/Makefile.in squid-3.1.8/helpers/external_acl/ip_user/Makefile.in
--- squid-3.1.7/helpers/external_acl/ip_user/Makefile.in 2010-08-24 17:42:25.000000000 +1200
+++ squid-3.1.8/helpers/external_acl/ip_user/Makefile.in 2010-09-04 15:26:22.000000000 +1200
@@ -36,6 +36,7 @@
$(top_srcdir)/src/Common.am
check_PROGRAMS =
TESTS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
libexec_PROGRAMS = ip_user_check$(EXEEXT)
subdir = helpers/external_acl/ip_user
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -273,7 +274,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES =
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir)
ip_user_check_SOURCES = \
dict.c \
ip_user.h \
diff -u -r -N squid-3.1.7/helpers/external_acl/ldap_group/Makefile.in squid-3.1.8/helpers/external_acl/ldap_group/Makefile.in
--- squid-3.1.7/helpers/external_acl/ldap_group/Makefile.in 2010-08-24 17:42:26.000000000 +1200
+++ squid-3.1.8/helpers/external_acl/ldap_group/Makefile.in 2010-09-04 15:26:23.000000000 +1200
@@ -36,6 +36,7 @@
$(top_srcdir)/src/Common.am ChangeLog
check_PROGRAMS =
TESTS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
libexec_PROGRAMS = squid_ldap_group$(EXEEXT)
subdir = helpers/external_acl/ldap_group
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -276,7 +277,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES =
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir)
man_MANS = squid_ldap_group.8
EXTRA_DIST = squid_ldap_group.8 config.test
squid_ldap_group_SOURCES = squid_ldap_group.c
diff -u -r -N squid-3.1.7/helpers/external_acl/session/Makefile.in squid-3.1.8/helpers/external_acl/session/Makefile.in
--- squid-3.1.7/helpers/external_acl/session/Makefile.in 2010-08-24 17:42:26.000000000 +1200
+++ squid-3.1.8/helpers/external_acl/session/Makefile.in 2010-09-04 15:26:23.000000000 +1200
@@ -36,6 +36,7 @@
$(top_srcdir)/src/Common.am
check_PROGRAMS =
TESTS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
libexec_PROGRAMS = squid_session$(EXEEXT)
subdir = helpers/external_acl/session
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -275,7 +276,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES =
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir)
man_MANS = squid_session.8
EXTRA_DIST = squid_session.8 config.test
squid_session_SOURCES = squid_session.c
diff -u -r -N squid-3.1.7/helpers/external_acl/unix_group/Makefile.in squid-3.1.8/helpers/external_acl/unix_group/Makefile.in
--- squid-3.1.7/helpers/external_acl/unix_group/Makefile.in 2010-08-24 17:42:27.000000000 +1200
+++ squid-3.1.8/helpers/external_acl/unix_group/Makefile.in 2010-09-04 15:26:23.000000000 +1200
@@ -36,6 +36,7 @@
$(top_srcdir)/src/Common.am
check_PROGRAMS =
TESTS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
libexec_PROGRAMS = squid_unix_group$(EXEEXT)
subdir = helpers/external_acl/unix_group
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -275,7 +276,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES =
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir)
man_MANS = squid_unix_group.8
EXTRA_DIST = squid_unix_group.8 config.test
squid_unix_group_SOURCES = check_group.c
diff -u -r -N squid-3.1.7/helpers/negotiate_auth/mswin_sspi/Makefile.in squid-3.1.8/helpers/negotiate_auth/mswin_sspi/Makefile.in
--- squid-3.1.7/helpers/negotiate_auth/mswin_sspi/Makefile.in 2010-08-24 17:42:27.000000000 +1200
+++ squid-3.1.8/helpers/negotiate_auth/mswin_sspi/Makefile.in 2010-09-04 15:26:24.000000000 +1200
@@ -42,6 +42,7 @@
$(top_srcdir)/src/Common.am
check_PROGRAMS =
TESTS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
libexec_PROGRAMS = mswin_negotiate_auth$(EXEEXT)
subdir = helpers/negotiate_auth/mswin_sspi
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -278,7 +279,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES =
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir)
mswin_negotiate_auth_SOURCES = libnegotiatessp.c negotiate_auth.c negotiate.h
LDADD = -L$(top_builddir)/lib -lsspwin32 -ladvapi32 -lmiscutil $(XTRA_LIBS)
EXTRA_DIST = readme.txt config.test
diff -u -r -N squid-3.1.7/helpers/ntlm_auth/fakeauth/Makefile.in squid-3.1.8/helpers/ntlm_auth/fakeauth/Makefile.in
--- squid-3.1.7/helpers/ntlm_auth/fakeauth/Makefile.in 2010-08-24 17:42:28.000000000 +1200
+++ squid-3.1.8/helpers/ntlm_auth/fakeauth/Makefile.in 2010-09-04 15:26:24.000000000 +1200
@@ -36,6 +36,7 @@
$(top_srcdir)/src/Common.am
check_PROGRAMS =
TESTS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
libexec_PROGRAMS = fakeauth_auth$(EXEEXT)
subdir = helpers/ntlm_auth/fakeauth
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -272,7 +273,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES =
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir)
fakeauth_auth_SOURCES = fakeauth_auth.c ntlm.h
LDADD = \
$(top_builddir)/compat/libcompat.la \
diff -u -r -N squid-3.1.7/helpers/ntlm_auth/mswin_sspi/Makefile.in squid-3.1.8/helpers/ntlm_auth/mswin_sspi/Makefile.in
--- squid-3.1.7/helpers/ntlm_auth/mswin_sspi/Makefile.in 2010-08-24 17:42:28.000000000 +1200
+++ squid-3.1.8/helpers/ntlm_auth/mswin_sspi/Makefile.in 2010-09-04 15:26:24.000000000 +1200
@@ -36,6 +36,7 @@
$(top_srcdir)/src/Common.am
check_PROGRAMS =
TESTS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
libexec_PROGRAMS = mswin_ntlm_auth$(EXEEXT)
subdir = helpers/ntlm_auth/mswin_sspi
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -272,7 +273,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES =
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir)
mswin_ntlm_auth_SOURCES = libntlmssp.c ntlm_auth.c ntlm.h
LDADD = \
$(top_builddir)/compat/libcompat.la \
diff -u -r -N squid-3.1.7/helpers/ntlm_auth/smb_lm/Makefile.in squid-3.1.8/helpers/ntlm_auth/smb_lm/Makefile.in
--- squid-3.1.7/helpers/ntlm_auth/smb_lm/Makefile.in 2010-08-24 17:42:29.000000000 +1200
+++ squid-3.1.8/helpers/ntlm_auth/smb_lm/Makefile.in 2010-09-04 15:26:24.000000000 +1200
@@ -36,6 +36,7 @@
$(top_srcdir)/src/Common.am
check_PROGRAMS =
TESTS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
libexec_PROGRAMS = ntlm_smb_lm_auth$(EXEEXT)
subdir = helpers/ntlm_auth/smb_lm
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -284,8 +285,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES =
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir) \
- -I$(srcdir)/smbval
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir) -I$(srcdir)/smbval
SUBDIRS = smbval
ntlm_smb_lm_auth_SOURCES = libntlmssp.c ntlm_smb_lm_auth.c ntlm_smb_lm_auth.h
LDADD = \
diff -u -r -N squid-3.1.7/helpers/ntlm_auth/smb_lm/smbval/Makefile.in squid-3.1.8/helpers/ntlm_auth/smb_lm/smbval/Makefile.in
--- squid-3.1.7/helpers/ntlm_auth/smb_lm/smbval/Makefile.in 2010-08-24 17:42:30.000000000 +1200
+++ squid-3.1.8/helpers/ntlm_auth/smb_lm/smbval/Makefile.in 2010-09-04 15:26:25.000000000 +1200
@@ -38,6 +38,7 @@
$(top_srcdir)/src/Common.am
check_PROGRAMS =
TESTS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
subdir = helpers/ntlm_auth/smb_lm/smbval
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
@@ -273,7 +274,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES =
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir)
noinst_LIBRARIES = libsmbvalid.a
libsmbvalid_a_SOURCES = valid.c session.c rfcnb-util.c rfcnb-io.c \
smblib-util.c smblib.c smbencrypt.c smbdes.c md4.c byteorder.h \
diff -u -r -N squid-3.1.7/include/squid_types.h squid-3.1.8/include/squid_types.h
--- squid-3.1.7/include/squid_types.h 2010-08-24 17:41:27.000000000 +1200
+++ squid-3.1.8/include/squid_types.h 2010-09-04 15:25:57.000000000 +1200
@@ -106,4 +106,14 @@
#endif
#endif
+#ifndef PRIX64
+#ifdef _SQUID_MSWIN_ /* Windows native port using MSVCRT */
+#define PRIX64 "I64X"
+#elif SIZEOF_INT64_T > SIZEOF_LONG
+#define PRIX64 "llX"
+#else
+#define PRIX64 "lX"
+#endif
+#endif
+
#endif /* SQUID_TYPES_H */
diff -u -r -N squid-3.1.7/include/version.h squid-3.1.8/include/version.h
--- squid-3.1.7/include/version.h 2010-08-24 17:43:37.000000000 +1200
+++ squid-3.1.8/include/version.h 2010-09-04 15:26:52.000000000 +1200
@@ -9,7 +9,7 @@
*/
#ifndef SQUID_RELEASE_TIME
-#define SQUID_RELEASE_TIME 1282628458
+#define SQUID_RELEASE_TIME 1283570743
#endif
#ifndef APP_SHORTNAME
diff -u -r -N squid-3.1.7/lib/Makefile.in squid-3.1.8/lib/Makefile.in
--- squid-3.1.7/lib/Makefile.in 2010-08-24 17:42:32.000000000 +1200
+++ squid-3.1.8/lib/Makefile.in 2010-09-04 15:26:25.000000000 +1200
@@ -42,7 +42,8 @@
strsep.c strtoll.c tempnam.c
check_PROGRAMS = tests/testAll$(EXEEXT)
TESTS = tests/testAll$(EXEEXT) testHeaders
-@USE_ESI_TRUE@am__append_1 = libTrie
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
+@USE_ESI_TRUE@am__append_2 = libTrie
subdir = lib
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
@@ -336,14 +337,9 @@
AM_CFLAGS = $(SQUID_CFLAGS)
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES = testHeaders
-INCLUDES = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/include \
- -I$(top_srcdir)/src \
- -I$(top_builddir)/include \
- $(SQUID_CPPUNIT_INC)
-
-SUBDIRS = $(am__append_1)
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1)
+SUBDIRS = $(am__append_2)
@ENABLE_XPROF_STATS_FALSE@XPROF_STATS_SOURCE =
@ENABLE_XPROF_STATS_TRUE@XPROF_STATS_SOURCE = Profiler.c
@ENABLE_WIN32SPECIFIC_FALSE@LIBSSPWIN32 =
diff -u -r -N squid-3.1.7/libltdl/libltdl/lt_dlloader.h squid-3.1.8/libltdl/libltdl/lt_dlloader.h
--- squid-3.1.7/libltdl/libltdl/lt_dlloader.h 2010-08-24 17:42:13.000000000 +1200
+++ squid-3.1.8/libltdl/libltdl/lt_dlloader.h 2010-09-04 15:26:17.000000000 +1200
@@ -31,7 +31,7 @@
#if !defined(LT_DLLOADER_H)
#define LT_DLLOADER_H 1
-#include "libltdl/lt_system.h"
+#include
LT_BEGIN_C_DECLS
diff -u -r -N squid-3.1.7/libltdl/libltdl/lt_error.h squid-3.1.8/libltdl/libltdl/lt_error.h
--- squid-3.1.7/libltdl/libltdl/lt_error.h 2010-08-24 17:42:13.000000000 +1200
+++ squid-3.1.8/libltdl/libltdl/lt_error.h 2010-09-04 15:26:17.000000000 +1200
@@ -32,7 +32,7 @@
#if !defined(LT_ERROR_H)
#define LT_ERROR_H 1
-#include "libltdl/lt_system.h"
+#include
LT_BEGIN_C_DECLS
diff -u -r -N squid-3.1.7/libltdl/libltdl/slist.h squid-3.1.8/libltdl/libltdl/slist.h
--- squid-3.1.7/libltdl/libltdl/slist.h 2010-08-24 17:42:13.000000000 +1200
+++ squid-3.1.8/libltdl/libltdl/slist.h 2010-09-04 15:26:17.000000000 +1200
@@ -42,8 +42,8 @@
#define SLIST_H 1
#if defined(LTDL)
-# include "libltdl/lt__glibc.h"
-# include "libltdl/lt_system.h"
+# include
+# include
#else
# define LT_SCOPE
#endif
diff -u -r -N squid-3.1.7/libltdl/ltdl.h squid-3.1.8/libltdl/ltdl.h
--- squid-3.1.7/libltdl/ltdl.h 2010-08-24 17:42:13.000000000 +1200
+++ squid-3.1.8/libltdl/ltdl.h 2010-09-04 15:26:17.000000000 +1200
@@ -33,9 +33,9 @@
#if !defined(LTDL_H)
#define LTDL_H 1
-#include "libltdl/lt_system.h"
-#include "libltdl/lt_error.h"
-#include "libltdl/lt_dlloader.h"
+#include
+#include
+#include
LT_BEGIN_C_DECLS
diff -u -r -N squid-3.1.7/RELEASENOTES.html squid-3.1.8/RELEASENOTES.html
--- squid-3.1.7/RELEASENOTES.html 2010-08-24 18:21:00.000000000 +1200
+++ squid-3.1.8/RELEASENOTES.html 2010-09-04 15:47:57.000000000 +1200
@@ -1,11 +1,11 @@
-
- Squid 3.1.7 release notes
+
+ Squid 3.1.8 release notes
-Squid 3.1.7 release notes
+Squid 3.1.8 release notes
Squid Developers
@@ -70,7 +70,7 @@
-The Squid Team are pleased to announce the release of Squid-3.1.7
+The Squid Team are pleased to announce the release of Squid-3.1.8
This new release is available for download from
http://www.squid-cache.org/Versions/v3/3.1/ or the
mirrors.
@@ -89,7 +89,6 @@
- The lack of some features available in Squid-2.x series. See the regression sections below for full details.
-- IPv6 split-stack support for Windows XP, MacOS X, OpenBSD and maybe others is not complete.
- CVE-2009-0801 : NAT interception vulnerability to malicious clients.
@@ -97,7 +96,6 @@
Currently known issues which only depends on available developer time and may still be resolved in a future 3.1 release are:
-- An ongoing slow FD leak introduced somewhere during the Squid-3.0 cycle.
- Windows support is still largely missing.
- AIX support for building with the IBM compiler is broken.
@@ -1337,8 +1335,8 @@
https_port intercept ssl-bump connection-auth[=on|off]
New port options. see http_port.
-icap_service bypass=on|off|1|0 routing=on|off|1|0
-New options 'bypass=' and 'routing='.
+
icap_service bypass=on|off|1|0 routing=on|off|1|0 ipv6=on|off
+New options 'bypass=', 'routing=' and 'ipv6='.
bypass=on|off|1|0
If set to 'on' or '1', the ICAP service is treated as
@@ -1365,6 +1363,11 @@
Routing is not allowed by default: the ICAP X-Next-Services
response header is ignored.
+
+ ipv6=on|off
+ Only has effect on split-stack systems. The default on those systems
+ is to use IPv4-only connections. When set to 'on' this option will
+ make Squid use IPv6-only connections to contact this ICAP service.
diff -u -r -N squid-3.1.7/src/acl/Makefile.in squid-3.1.8/src/acl/Makefile.in
--- squid-3.1.7/src/acl/Makefile.in 2010-08-24 17:42:37.000000000 +1200
+++ squid-3.1.8/src/acl/Makefile.in 2010-09-04 15:26:27.000000000 +1200
@@ -35,8 +35,9 @@
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(top_srcdir)/src/Common.am $(top_srcdir)/src/TestHeaders.am
check_PROGRAMS =
-@ENABLE_SSL_TRUE@am__append_1 = $(SSL_ACLS)
-@ENABLE_ARP_ACL_TRUE@am__append_2 = $(ARP_ACLS)
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
+@ENABLE_SSL_TRUE@am__append_2 = $(SSL_ACLS)
+@ENABLE_ARP_ACL_TRUE@am__append_3 = $(ARP_ACLS)
subdir = src/acl
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
@@ -318,13 +319,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES = testHeaders
TESTS = testHeaders
-INCLUDES = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/include \
- -I$(top_srcdir)/src \
- -I$(top_builddir)/include \
- $(SQUID_CPPUNIT_INC)
-
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1)
noinst_LTLIBRARIES = libapi.la libstate.la libacls.la
libapi_la_SOURCES = \
Acl.cc \
@@ -357,8 +353,8 @@
RequestMimeType.cc RequestMimeType.h SourceAsn.h \
SourceDomain.cc SourceDomain.h SourceIp.cc SourceIp.h Tag.cc \
Tag.h Url.cc Url.h UrlPath.cc UrlPath.h UrlPort.cc UrlPort.h \
- UserData.cc UserData.h Gadgets.cc Gadgets.h $(am__append_1) \
- $(am__append_2)
+ UserData.cc UserData.h Gadgets.cc Gadgets.h $(am__append_2) \
+ $(am__append_3)
EXTRA_libacls_la_SOURCES = $(SSL_ACLS) $(ARP_ACLS)
SSL_ACLS = \
CertificateData.cc \
diff -u -r -N squid-3.1.7/src/adaptation/AccessCheck.cc squid-3.1.8/src/adaptation/AccessCheck.cc
--- squid-3.1.7/src/adaptation/AccessCheck.cc 2010-08-24 17:41:27.000000000 +1200
+++ squid-3.1.8/src/adaptation/AccessCheck.cc 2010-09-04 15:25:57.000000000 +1200
@@ -23,8 +23,9 @@
if (Config::Enabled) {
// the new check will call the callback and delete self, eventually
- return AsyncStart(new AccessCheck(
- ServiceFilter(method, vp, req, rep), cb, cbdata));
+ AsyncJob::Start(new AccessCheck( // we do not store so not a CbcPointer
+ ServiceFilter(method, vp, req, rep), cb, cbdata));
+ return true;
}
debugs(83, 3, HERE << "adaptation off, skipping");
diff -u -r -N squid-3.1.7/src/adaptation/ecap/Makefile.in squid-3.1.8/src/adaptation/ecap/Makefile.in
--- squid-3.1.7/src/adaptation/ecap/Makefile.in 2010-08-24 17:42:38.000000000 +1200
+++ squid-3.1.8/src/adaptation/ecap/Makefile.in 2010-09-04 15:26:27.000000000 +1200
@@ -35,6 +35,7 @@
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(top_srcdir)/src/Common.am $(top_srcdir)/src/TestHeaders.am
check_PROGRAMS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
subdir = src/adaptation/ecap
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
@@ -275,13 +276,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES = testHeaders
TESTS = testHeaders
-INCLUDES = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/include \
- -I$(top_srcdir)/src \
- -I$(top_builddir)/include \
- $(SQUID_CPPUNIT_INC)
-
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1)
noinst_LTLIBRARIES = libecap.la
libecap_la_SOURCES = \
Config.h \
diff -u -r -N squid-3.1.7/src/adaptation/ecap/ServiceRep.cc squid-3.1.8/src/adaptation/ecap/ServiceRep.cc
--- squid-3.1.7/src/adaptation/ecap/ServiceRep.cc 2010-08-24 17:41:25.000000000 +1200
+++ squid-3.1.8/src/adaptation/ecap/ServiceRep.cc 2010-09-04 15:25:57.000000000 +1200
@@ -57,11 +57,11 @@
}
Adaptation::Initiate *
-Adaptation::Ecap::ServiceRep::makeXactLauncher(Adaptation::Initiator *initiator,
- HttpMsg *virgin, HttpRequest *cause)
+Adaptation::Ecap::ServiceRep::makeXactLauncher(HttpMsg *virgin,
+ HttpRequest *cause)
{
Must(up());
- XactionRep *rep = new XactionRep(initiator, virgin, cause, Pointer(this));
+ XactionRep *rep = new XactionRep(virgin, cause, Pointer(this));
XactionRep::AdapterXaction x(theService->makeXaction(rep));
rep->master(x);
return rep;
diff -u -r -N squid-3.1.7/src/adaptation/ecap/ServiceRep.h squid-3.1.8/src/adaptation/ecap/ServiceRep.h
--- squid-3.1.7/src/adaptation/ecap/ServiceRep.h 2010-08-24 17:41:26.000000000 +1200
+++ squid-3.1.8/src/adaptation/ecap/ServiceRep.h 2010-09-04 15:25:57.000000000 +1200
@@ -33,7 +33,7 @@
virtual bool probed() const;
virtual bool up() const;
- Adaptation::Initiate *makeXactLauncher(Adaptation::Initiator *, HttpMsg *virginHeader, HttpRequest *virginCause);
+ Adaptation::Initiate *makeXactLauncher(HttpMsg *virginHeader, HttpRequest *virginCause);
// the methods below can only be called on an up() service
virtual bool wantsUrl(const String &urlPath) const;
diff -u -r -N squid-3.1.7/src/adaptation/ecap/XactionRep.cc squid-3.1.8/src/adaptation/ecap/XactionRep.cc
--- squid-3.1.7/src/adaptation/ecap/XactionRep.cc 2010-08-24 17:41:26.000000000 +1200
+++ squid-3.1.8/src/adaptation/ecap/XactionRep.cc 2010-09-04 15:25:58.000000000 +1200
@@ -14,11 +14,11 @@
CBDATA_NAMESPACED_CLASS_INIT(Adaptation::Ecap::XactionRep, XactionRep);
-Adaptation::Ecap::XactionRep::XactionRep(Adaptation::Initiator *anInitiator,
- HttpMsg *virginHeader, HttpRequest *virginCause,
- const Adaptation::ServicePointer &aService):
+Adaptation::Ecap::XactionRep::XactionRep(
+ HttpMsg *virginHeader, HttpRequest *virginCause,
+ const Adaptation::ServicePointer &aService):
AsyncJob("Adaptation::Ecap::XactionRep"),
- Adaptation::Initiate("Adaptation::Ecap::XactionRep", anInitiator),
+ Adaptation::Initiate("Adaptation::Ecap::XactionRep"),
theService(aService),
theVirginRep(virginHeader), theCauseRep(NULL),
proxyingVb(opUndecided), proxyingAb(opUndecided),
@@ -430,9 +430,8 @@
const BodyPipePointer &vp = theVirginRep.raw().body_pipe;
if (!canAccessVb)
buf.append("x", 1);
- if (vp != NULL && vp->stillConsuming(this)) {
+ if (vp != NULL) { // XXX: but may not be stillConsuming()
buf.append("Vb", 2);
- buf.append(vp->status(), strlen(vp->status())); // XXX
} else
buf.append("V.", 2);
}
@@ -441,9 +440,8 @@
MessageRep *rep = dynamic_cast(theAnswerRep.get());
Must(rep);
const BodyPipePointer &ap = rep->raw().body_pipe;
- if (ap != NULL && ap->stillProducing(this)) {
+ if (ap != NULL) { // XXX: but may not be stillProducing()
buf.append(" Ab", 3);
- buf.append(ap->status(), strlen(ap->status())); // XXX
} else
buf.append(" A.", 3);
}
diff -u -r -N squid-3.1.7/src/adaptation/ecap/XactionRep.h squid-3.1.8/src/adaptation/ecap/XactionRep.h
--- squid-3.1.7/src/adaptation/ecap/XactionRep.h 2010-08-24 17:41:27.000000000 +1200
+++ squid-3.1.8/src/adaptation/ecap/XactionRep.h 2010-09-04 15:25:57.000000000 +1200
@@ -28,7 +28,7 @@
public BodyConsumer, public BodyProducer
{
public:
- XactionRep(Adaptation::Initiator *anInitiator, HttpMsg *virginHeader, HttpRequest *virginCause, const Adaptation::ServicePointer &service);
+ XactionRep(HttpMsg *virginHeader, HttpRequest *virginCause, const Adaptation::ServicePointer &service);
virtual ~XactionRep();
typedef libecap::shared_ptr AdapterXaction;
diff -u -r -N squid-3.1.7/src/adaptation/icap/Launcher.cc squid-3.1.8/src/adaptation/icap/Launcher.cc
--- squid-3.1.7/src/adaptation/icap/Launcher.cc 2010-08-24 17:41:26.000000000 +1200
+++ squid-3.1.8/src/adaptation/icap/Launcher.cc 2010-09-04 15:25:57.000000000 +1200
@@ -15,9 +15,9 @@
Adaptation::Icap::Launcher::Launcher(const char *aTypeName,
- Adaptation::Initiator *anInitiator, Adaptation::ServicePointer &aService):
+ Adaptation::ServicePointer &aService):
AsyncJob(aTypeName),
- Adaptation::Initiate(aTypeName, anInitiator),
+ Adaptation::Initiate(aTypeName),
theService(aService), theXaction(0), theLaunches(0)
{
}
@@ -31,7 +31,7 @@
{
Adaptation::Initiate::start();
- Must(theInitiator);
+ Must(theInitiator.set());
launchXaction("first");
}
@@ -47,7 +47,7 @@
if (theLaunches >= TheConfig.repeat_limit)
x->disableRepeats("over icap_retry_limit");
theXaction = initiateAdaptation(x);
- Must(theXaction);
+ Must(initiated(theXaction));
}
void Adaptation::Icap::Launcher::noteAdaptationAnswer(HttpMsg *message)
@@ -76,7 +76,7 @@
Must(done()); // swanSong will notify the initiator
}
-void Adaptation::Icap::Launcher::noteXactAbort(XactAbortInfo &info)
+void Adaptation::Icap::Launcher::noteXactAbort(XactAbortInfo info)
{
debugs(93,5, HERE << "theXaction:" << theXaction << " launches: " << theLaunches);
@@ -102,10 +102,10 @@
void Adaptation::Icap::Launcher::swanSong()
{
- if (theInitiator)
+ if (theInitiator.set())
tellQueryAborted(true); // always final here because abnormal
- if (theXaction)
+ if (theXaction.set())
clearAdaptation(theXaction);
Adaptation::Initiate::swanSong();
diff -u -r -N squid-3.1.7/src/adaptation/icap/Launcher.h squid-3.1.8/src/adaptation/icap/Launcher.h
--- squid-3.1.7/src/adaptation/icap/Launcher.h 2010-08-24 17:41:27.000000000 +1200
+++ squid-3.1.8/src/adaptation/icap/Launcher.h 2010-09-04 15:25:57.000000000 +1200
@@ -73,7 +73,7 @@
class Launcher: public Adaptation::Initiate, public Adaptation::Initiator
{
public:
- Launcher(const char *aTypeName, Adaptation::Initiator *anInitiator, Adaptation::ServicePointer &aService);
+ Launcher(const char *aTypeName, Adaptation::ServicePointer &aService);
virtual ~Launcher();
// Adaptation::Initiate: asynchronous communication with the initiator
@@ -81,7 +81,7 @@
// Adaptation::Initiator: asynchronous communication with the current transaction
virtual void noteAdaptationAnswer(HttpMsg *message);
- virtual void noteXactAbort(XactAbortInfo &info);
+ virtual void noteXactAbort(XactAbortInfo info);
private:
bool canRetry(XactAbortInfo &info) const; //< true if can retry in the case of persistent connection failures
@@ -100,7 +100,7 @@
void launchXaction(const char *xkind);
Adaptation::ServicePointer theService; ///< ICAP service for all launches
- Adaptation::Initiate *theXaction; ///< current ICAP transaction
+ CbcPointer theXaction; ///< current ICAP transaction
int theLaunches; // the number of transaction launches
};
@@ -114,6 +114,10 @@
XactAbortInfo(const XactAbortInfo &);
~XactAbortInfo();
+ std::ostream &print(std::ostream &os) const {
+ return os << isRetriable << ',' << isRepeatable;
+ }
+
HttpRequest *icapRequest;
HttpReply *icapReply;
bool isRetriable;
@@ -123,31 +127,13 @@
XactAbortInfo &operator =(const XactAbortInfo &); // undefined
};
-/* required by UnaryMemFunT */
-inline std::ostream &operator << (std::ostream &os, Adaptation::Icap::XactAbortInfo info)
+inline
+std::ostream &
+operator <<(std::ostream &os, const XactAbortInfo &xai)
{
- // Nothing, it is unused
- return os;
+ return xai.print(os);
}
-/// A Dialer class used to schedule the Adaptation::Icap::Launcher::noteXactAbort call
-class XactAbortCall: public UnaryMemFunT
-{
-public:
- typedef void (Adaptation::Icap::Launcher::*DialMethod)(Adaptation::Icap::XactAbortInfo &);
- XactAbortCall(Adaptation::Icap::Launcher *launcer, DialMethod aMethod,
- const Adaptation::Icap::XactAbortInfo &info):
- UnaryMemFunT(launcer, NULL, info),
- dialMethod(aMethod) {}
- virtual void print(std::ostream &os) const { os << '(' << "retriable:" << arg1.isRetriable << ", repeatable:" << arg1.isRepeatable << ')'; }
-
-public:
- DialMethod dialMethod;
-
-protected:
- virtual void doDial() { (object->*dialMethod)(arg1); }
-};
-
} // namespace Icap
} // namespace Adaptation
diff -u -r -N squid-3.1.7/src/adaptation/icap/Makefile.in squid-3.1.8/src/adaptation/icap/Makefile.in
--- squid-3.1.7/src/adaptation/icap/Makefile.in 2010-08-24 17:42:39.000000000 +1200
+++ squid-3.1.8/src/adaptation/icap/Makefile.in 2010-09-04 15:26:27.000000000 +1200
@@ -35,6 +35,7 @@
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(top_srcdir)/src/Common.am $(top_srcdir)/src/TestHeaders.am
check_PROGRAMS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
subdir = src/adaptation/icap
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
@@ -276,13 +277,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES = testHeaders
TESTS = testHeaders
-INCLUDES = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/include \
- -I$(top_srcdir)/src \
- -I$(top_builddir)/include \
- $(SQUID_CPPUNIT_INC)
-
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1)
noinst_LTLIBRARIES = libicap.la
libicap_la_SOURCES = \
Client.cc \
diff -u -r -N squid-3.1.7/src/adaptation/icap/ModXact.cc squid-3.1.8/src/adaptation/icap/ModXact.cc
--- squid-3.1.7/src/adaptation/icap/ModXact.cc 2010-08-24 17:41:26.000000000 +1200
+++ squid-3.1.8/src/adaptation/icap/ModXact.cc 2010-09-04 15:25:57.000000000 +1200
@@ -37,10 +37,10 @@
memset(this, 0, sizeof(*this));
}
-Adaptation::Icap::ModXact::ModXact(Adaptation::Initiator *anInitiator, HttpMsg *virginHeader,
+Adaptation::Icap::ModXact::ModXact(HttpMsg *virginHeader,
HttpRequest *virginCause, Adaptation::Icap::ServiceRep::Pointer &aService):
AsyncJob("Adaptation::Icap::ModXact"),
- Adaptation::Icap::Xaction("Adaptation::Icap::ModXact", anInitiator, aService),
+ Adaptation::Icap::Xaction("Adaptation::Icap::ModXact", aService),
virginConsumed(0),
bodyParser(NULL),
canStartBypass(false), // too early
@@ -94,8 +94,9 @@
Must(!state.serviceWaiting);
debugs(93, 7, HERE << "will wait for the ICAP service" << status());
state.serviceWaiting = true;
- AsyncCall::Pointer call = asyncCall(93,5, "Adaptation::Icap::ModXact::noteServiceReady",
- MemFun(this, &Adaptation::Icap::ModXact::noteServiceReady));
+ typedef NullaryMemFunT Dialer;
+ AsyncCall::Pointer call = JobCallback(93,5,
+ Dialer, this, Adaptation::Icap::ModXact::noteServiceReady);
service().callWhenReady(call);
}
@@ -1681,9 +1682,9 @@
/* Adaptation::Icap::ModXactLauncher */
-Adaptation::Icap::ModXactLauncher::ModXactLauncher(Adaptation::Initiator *anInitiator, HttpMsg *virginHeader, HttpRequest *virginCause, Adaptation::ServicePointer aService):
+Adaptation::Icap::ModXactLauncher::ModXactLauncher(HttpMsg *virginHeader, HttpRequest *virginCause, Adaptation::ServicePointer aService):
AsyncJob("Adaptation::Icap::ModXactLauncher"),
- Adaptation::Icap::Launcher("Adaptation::Icap::ModXactLauncher", anInitiator, aService)
+ Adaptation::Icap::Launcher("Adaptation::Icap::ModXactLauncher", aService)
{
virgin.setHeader(virginHeader);
virgin.setCause(virginCause);
@@ -1695,7 +1696,7 @@
Adaptation::Icap::ServiceRep::Pointer s =
dynamic_cast(theService.getRaw());
Must(s != NULL);
- return new Adaptation::Icap::ModXact(this, virgin.header, virgin.cause, s);
+ return new Adaptation::Icap::ModXact(virgin.header, virgin.cause, s);
}
void Adaptation::Icap::ModXactLauncher::swanSong()
diff -u -r -N squid-3.1.7/src/adaptation/icap/ModXact.h squid-3.1.8/src/adaptation/icap/ModXact.h
--- squid-3.1.7/src/adaptation/icap/ModXact.h 2010-08-24 17:41:27.000000000 +1200
+++ squid-3.1.8/src/adaptation/icap/ModXact.h 2010-09-04 15:25:57.000000000 +1200
@@ -136,7 +136,7 @@
{
public:
- ModXact(Adaptation::Initiator *anInitiator, HttpMsg *virginHeader, HttpRequest *virginCause, ServiceRep::Pointer &s);
+ ModXact(HttpMsg *virginHeader, HttpRequest *virginCause, ServiceRep::Pointer &s);
// BodyProducer methods
virtual void noteMoreBodySpaceAvailable(BodyPipe::Pointer);
@@ -161,7 +161,6 @@
InOut virgin;
InOut adapted;
-protected:
// bypasses exceptions if needed and possible
virtual void callException(const std::exception &e);
@@ -322,7 +321,7 @@
class ModXactLauncher: public Launcher
{
public:
- ModXactLauncher(Adaptation::Initiator *anInitiator, HttpMsg *virginHeader, HttpRequest *virginCause, Adaptation::ServicePointer s);
+ ModXactLauncher(HttpMsg *virginHeader, HttpRequest *virginCause, Adaptation::ServicePointer s);
protected:
virtual Xaction *createXaction();
diff -u -r -N squid-3.1.7/src/adaptation/icap/OptXact.cc squid-3.1.8/src/adaptation/icap/OptXact.cc
--- squid-3.1.7/src/adaptation/icap/OptXact.cc 2010-08-24 17:41:26.000000000 +1200
+++ squid-3.1.8/src/adaptation/icap/OptXact.cc 2010-09-04 15:25:58.000000000 +1200
@@ -16,9 +16,9 @@
CBDATA_NAMESPACED_CLASS_INIT(Adaptation::Icap, OptXactLauncher);
-Adaptation::Icap::OptXact::OptXact(Adaptation::Initiator *anInitiator, Adaptation::Icap::ServiceRep::Pointer &aService):
+Adaptation::Icap::OptXact::OptXact(Adaptation::Icap::ServiceRep::Pointer &aService):
AsyncJob("Adaptation::Icap::OptXact"),
- Adaptation::Icap::Xaction("Adaptation::Icap::OptXact", anInitiator, aService)
+ Adaptation::Icap::Xaction("Adaptation::Icap::OptXact", aService)
{
}
@@ -111,9 +111,9 @@
/* Adaptation::Icap::OptXactLauncher */
-Adaptation::Icap::OptXactLauncher::OptXactLauncher(Adaptation::Initiator *anInitiator, Adaptation::ServicePointer aService):
+Adaptation::Icap::OptXactLauncher::OptXactLauncher(Adaptation::ServicePointer aService):
AsyncJob("Adaptation::Icap::OptXactLauncher"),
- Adaptation::Icap::Launcher("Adaptation::Icap::OptXactLauncher", anInitiator, aService)
+ Adaptation::Icap::Launcher("Adaptation::Icap::OptXactLauncher", aService)
{
}
@@ -122,5 +122,5 @@
Adaptation::Icap::ServiceRep::Pointer s =
dynamic_cast(theService.getRaw());
Must(s != NULL);
- return new Adaptation::Icap::OptXact(this, s);
+ return new Adaptation::Icap::OptXact(s);
}
diff -u -r -N squid-3.1.7/src/adaptation/icap/OptXact.h squid-3.1.8/src/adaptation/icap/OptXact.h
--- squid-3.1.7/src/adaptation/icap/OptXact.h 2010-08-24 17:41:27.000000000 +1200
+++ squid-3.1.8/src/adaptation/icap/OptXact.h 2010-09-04 15:25:58.000000000 +1200
@@ -51,7 +51,7 @@
{
public:
- OptXact(Adaptation::Initiator *anInitiator, ServiceRep::Pointer &aService);
+ OptXact(ServiceRep::Pointer &aService);
protected:
virtual void start();
@@ -76,7 +76,7 @@
class OptXactLauncher: public Launcher
{
public:
- OptXactLauncher(Adaptation::Initiator *anInitiator, Adaptation::ServicePointer aService);
+ OptXactLauncher(Adaptation::ServicePointer aService);
protected:
virtual Xaction *createXaction();
diff -u -r -N squid-3.1.7/src/adaptation/icap/ServiceRep.cc squid-3.1.8/src/adaptation/icap/ServiceRep.cc
--- squid-3.1.7/src/adaptation/icap/ServiceRep.cc 2010-08-24 17:41:26.000000000 +1200
+++ squid-3.1.8/src/adaptation/icap/ServiceRep.cc 2010-09-04 15:25:57.000000000 +1200
@@ -135,7 +135,7 @@
if (!detached())
updateScheduled = false;
- if (detached() || theOptionsFetcher) {
+ if (detached() || theOptionsFetcher.set()) {
debugs(93,5, HERE << "ignores options update " << status());
return;
}
@@ -188,7 +188,7 @@
i.callback = cb;
theClients.push_back(i);
- if (theOptionsFetcher || notifying)
+ if (theOptionsFetcher.set() || notifying)
return; // do nothing, we will be picked up in noteTimeToNotify()
if (needNewOptions())
@@ -200,7 +200,7 @@
void Adaptation::Icap::ServiceRep::scheduleNotification()
{
debugs(93,7, HERE << "will notify " << theClients.size() << " clients");
- CallJobHere(93, 5, this, Adaptation::Icap::ServiceRep::noteTimeToNotify);
+ CallJobHere(93, 5, this, Adaptation::Icap::ServiceRep, noteTimeToNotify);
}
bool Adaptation::Icap::ServiceRep::needNewOptions() const
@@ -294,7 +294,7 @@
// we are receiving ICAP OPTIONS response headers here or NULL on failures
void Adaptation::Icap::ServiceRep::noteAdaptationAnswer(HttpMsg *msg)
{
- Must(theOptionsFetcher);
+ Must(initiated(theOptionsFetcher));
clearAdaptation(theOptionsFetcher);
Must(msg);
@@ -314,13 +314,23 @@
void Adaptation::Icap::ServiceRep::noteAdaptationQueryAbort(bool)
{
- Must(theOptionsFetcher);
+ Must(initiated(theOptionsFetcher));
clearAdaptation(theOptionsFetcher);
debugs(93,3, HERE << "failed to fetch options " << status());
handleNewOptions(0);
}
+// we (a) must keep trying to get OPTIONS and (b) are RefCounted so we
+// must keep our job alive (XXX: until nobody needs us)
+void Adaptation::Icap::ServiceRep::callException(const std::exception &e)
+{
+ clearAdaptation(theOptionsFetcher);
+ debugs(93,2, "ICAP probably failed to fetch options (" << e.what() <<
+ ")" << status());
+ handleNewOptions(0);
+}
+
void Adaptation::Icap::ServiceRep::handleNewOptions(Adaptation::Icap::Options *newOptions)
{
// new options may be NULL
@@ -337,9 +347,9 @@
Must(!theOptionsFetcher);
debugs(93,6, HERE << "will get new options " << status());
- // XXX: second "this" is "self"; this works but may stop if API changes
- theOptionsFetcher = initiateAdaptation(new Adaptation::Icap::OptXactLauncher(this, this));
- Must(theOptionsFetcher);
+ // XXX: "this" here is "self"; works until refcounting API changes
+ theOptionsFetcher = initiateAdaptation(
+ new Adaptation::Icap::OptXactLauncher(this));
// TODO: timeout in case Adaptation::Icap::OptXact never calls us back?
// Such a timeout should probably be a generic AsyncStart feature.
}
@@ -406,10 +416,10 @@
}
Adaptation::Initiate *
-Adaptation::Icap::ServiceRep::makeXactLauncher(Adaptation::Initiator *initiator,
- HttpMsg *virgin, HttpRequest *cause)
+Adaptation::Icap::ServiceRep::makeXactLauncher(HttpMsg *virgin,
+ HttpRequest *cause)
{
- return new Adaptation::Icap::ModXactLauncher(initiator, virgin, cause, this);
+ return new Adaptation::Icap::ModXactLauncher(virgin, cause, this);
}
// returns a temporary string depicting service status, for debugging
@@ -438,7 +448,7 @@
if (detached())
buf.append(",detached", 9);
- if (theOptionsFetcher)
+ if (theOptionsFetcher.set())
buf.append(",fetch", 6);
if (notifying)
diff -u -r -N squid-3.1.7/src/adaptation/icap/ServiceRep.h squid-3.1.8/src/adaptation/icap/ServiceRep.h
--- squid-3.1.7/src/adaptation/icap/ServiceRep.h 2010-08-24 17:41:26.000000000 +1200
+++ squid-3.1.8/src/adaptation/icap/ServiceRep.h 2010-09-04 15:25:57.000000000 +1200
@@ -94,7 +94,7 @@
virtual bool probed() const; // see comments above
virtual bool up() const; // see comments above
- virtual Adaptation::Initiate *makeXactLauncher(Adaptation::Initiator *, HttpMsg *virginHeader, HttpRequest *virginCause);
+ virtual Initiate *makeXactLauncher(HttpMsg *virginHeader, HttpRequest *virginCause);
void callWhenReady(AsyncCall::Pointer &cb);
@@ -107,6 +107,7 @@
//AsyncJob virtual methods
virtual bool doneAll() const { return Adaptation::Initiator::doneAll() && false;}
+ virtual void callException(const std::exception &e);
virtual void detach();
virtual bool detached() const;
@@ -131,7 +132,7 @@
Clients theClients; // all clients waiting for a call back
Options *theOptions;
- Adaptation::Initiate *theOptionsFetcher; // pending ICAP OPTIONS transaction
+ CbcPointer theOptionsFetcher; // pending ICAP OPTIONS transaction
time_t theLastUpdate; // time the options were last updated
static const int TheSessionFailureLimit;
diff -u -r -N squid-3.1.7/src/adaptation/icap/Xaction.cc squid-3.1.8/src/adaptation/icap/Xaction.cc
--- squid-3.1.7/src/adaptation/icap/Xaction.cc 2010-08-24 17:41:27.000000000 +1200
+++ squid-3.1.8/src/adaptation/icap/Xaction.cc 2010-09-04 15:25:57.000000000 +1200
@@ -24,9 +24,10 @@
//CBDATA_NAMESPACED_CLASS_INIT(Adaptation::Icap, Xaction);
-Adaptation::Icap::Xaction::Xaction(const char *aTypeName, Adaptation::Initiator *anInitiator, Adaptation::Icap::ServiceRep::Pointer &aService):
+Adaptation::Icap::Xaction::Xaction(const char *aTypeName,
+ Adaptation::Icap::ServiceRep::Pointer &aService):
AsyncJob(aTypeName),
- Adaptation::Initiate(aTypeName, anInitiator),
+ Adaptation::Initiate(aTypeName),
icapRequest(NULL),
icapReply(NULL),
attempts(0),
@@ -105,7 +106,8 @@
// fake the connect callback
// TODO: can we sync call Adaptation::Icap::Xaction::noteCommConnected here instead?
typedef CommCbMemFunT Dialer;
- Dialer dialer(this, &Adaptation::Icap::Xaction::noteCommConnected);
+ CbcPointer self(this);
+ Dialer dialer(self, &Adaptation::Icap::Xaction::noteCommConnected);
dialer.params.fd = connection;
dialer.params.flag = COMM_OK;
// fake other parameters by copying from the existing connection
@@ -136,20 +138,19 @@
// TODO: service bypass status may differ from that of a transaction
typedef CommCbMemFunT TimeoutDialer;
- AsyncCall::Pointer timeoutCall = asyncCall(93, 5, "Adaptation::Icap::Xaction::noteCommTimedout",
- TimeoutDialer(this,&Adaptation::Icap::Xaction::noteCommTimedout));
-
+ AsyncCall::Pointer timeoutCall = JobCallback(93, 5,
+ TimeoutDialer, this, Adaptation::Icap::Xaction::noteCommTimedout);
commSetTimeout(connection, TheConfig.connect_timeout(
service().cfg().bypass), timeoutCall);
typedef CommCbMemFunT CloseDialer;
- closer = asyncCall(93, 5, "Adaptation::Icap::Xaction::noteCommClosed",
- CloseDialer(this,&Adaptation::Icap::Xaction::noteCommClosed));
+ closer = JobCallback(93, 5,
+ CloseDialer, this, Adaptation::Icap::Xaction::noteCommClosed);
comm_add_close_handler(connection, closer);
typedef CommCbMemFunT ConnectDialer;
- connector = asyncCall(93,3, "Adaptation::Icap::Xaction::noteCommConnected",
- ConnectDialer(this, &Adaptation::Icap::Xaction::noteCommConnected));
+ connector = JobCallback(93,3,
+ ConnectDialer, this, Adaptation::Icap::Xaction::noteCommConnected);
commConnectStart(connection, s.cfg().host.termedBuf(), s.cfg().port, connector);
}
@@ -233,8 +234,8 @@
{
// comm module will free the buffer
typedef CommCbMemFunT Dialer;
- writer = asyncCall(93,3, "Adaptation::Icap::Xaction::noteCommWrote",
- Dialer(this, &Adaptation::Icap::Xaction::noteCommWrote));
+ writer = JobCallback(93,3,
+ Dialer, this, Adaptation::Icap::Xaction::noteCommWrote);
comm_write_mbuf(connection, &buf, writer);
updateTimeout();
@@ -316,8 +317,8 @@
// XXX: why does Config.Timeout lacks a write timeout?
// TODO: service bypass status may differ from that of a transaction
typedef CommCbMemFunT TimeoutDialer;
- AsyncCall::Pointer call = asyncCall(93, 5, "Adaptation::Icap::Xaction::noteCommTimedout",
- TimeoutDialer(this,&Adaptation::Icap::Xaction::noteCommTimedout));
+ AsyncCall::Pointer call = JobCallback(93,5,
+ TimeoutDialer, this, Adaptation::Icap::Xaction::noteCommTimedout);
commSetTimeout(connection,
TheConfig.io_timeout(service().cfg().bypass), call);
@@ -340,8 +341,8 @@
* here instead of reading directly into readBuf.buf.
*/
typedef CommCbMemFunT Dialer;
- reader = asyncCall(93,3, "Adaptation::Icap::Xaction::noteCommRead",
- Dialer(this, &Adaptation::Icap::Xaction::noteCommRead));
+ reader = JobCallback(93,3,
+ Dialer, this, Adaptation::Icap::Xaction::noteCommRead);
comm_read(connection, commBuf, readBuf.spaceSize(), reader);
updateTimeout();
@@ -431,7 +432,7 @@
void Adaptation::Icap::Xaction::noteInitiatorAborted()
{
- if (theInitiator) {
+ if (theInitiator.set()) {
clearInitiator();
mustStop("initiator aborted");
}
@@ -464,8 +465,7 @@
if (commBuf)
memFreeBuf(commBufSize, commBuf);
- if (theInitiator)
- tellQueryAborted();
+ tellQueryAborted();
maybeLog();
@@ -474,12 +474,15 @@
void Adaptation::Icap::Xaction::tellQueryAborted()
{
- Adaptation::Icap::Launcher *l = dynamic_cast(theInitiator.ptr());
- Adaptation::Icap::XactAbortInfo abortInfo(icapRequest, icapReply, retriable(), repeatable());
- CallJob(91, 5, __FILE__, __LINE__,
- "Adaptation::Icap::Launcher::noteXactAbort",
- XactAbortCall(l, &Adaptation::Icap::Launcher::noteXactAbort, abortInfo) );
- clearInitiator();
+ if (theInitiator.set()) {
+ Adaptation::Icap::XactAbortInfo abortInfo(icapRequest, icapReply,
+ retriable(), repeatable());
+ Launcher *launcher = dynamic_cast(theInitiator.get());
+ // launcher may be nil if initiator is invalid
+ CallJobHere1(91,5, CbcPointer(launcher),
+ Launcher, noteXactAbort, abortInfo);
+ clearInitiator();
+ }
}
diff -u -r -N squid-3.1.7/src/adaptation/icap/Xaction.h squid-3.1.8/src/adaptation/icap/Xaction.h
--- squid-3.1.7/src/adaptation/icap/Xaction.h 2010-08-24 17:41:25.000000000 +1200
+++ squid-3.1.8/src/adaptation/icap/Xaction.h 2010-09-04 15:25:57.000000000 +1200
@@ -63,7 +63,7 @@
{
public:
- Xaction(const char *aTypeName, Adaptation::Initiator *anInitiator, ServiceRep::Pointer &aService);
+ Xaction(const char *aTypeName, ServiceRep::Pointer &aService);
virtual ~Xaction();
void disableRetries();
@@ -125,10 +125,12 @@
// useful for debugging
virtual bool fillVirginHttpHeader(MemBuf&) const;
+public:
// custom exception handling and end-of-call checks
virtual void callException(const std::exception &e);
virtual void callEnd();
+protected:
// logging
void setOutcome(const XactOutcome &xo);
virtual void finalizeLogInfo();
diff -u -r -N squid-3.1.7/src/adaptation/Initiate.cc squid-3.1.8/src/adaptation/Initiate.cc
--- squid-3.1.7/src/adaptation/Initiate.cc 2010-08-24 17:41:26.000000000 +1200
+++ squid-3.1.8/src/adaptation/Initiate.cc 2010-09-04 15:25:58.000000000 +1200
@@ -6,6 +6,7 @@
#include "HttpMsg.h"
#include "adaptation/Initiator.h"
#include "adaptation/Initiate.h"
+#include "base/AsyncJobCalls.h"
namespace Adaptation
{
@@ -17,11 +18,13 @@
public:
typedef UnaryMemFunT Parent;
- AnswerDialer(Initiator *obj, Parent::Method meth, HttpMsg *msg):
- Parent(obj, meth, msg) { HTTPMSGLOCK(arg1); }
- AnswerDialer(const AnswerDialer &d):
- Parent(d) { HTTPMSGLOCK(arg1); }
+ AnswerDialer(const Parent::JobPointer &job, Parent::Method meth,
+ HttpMsg *msg): Parent(job, meth, msg) { HTTPMSGLOCK(arg1); }
+ AnswerDialer(const AnswerDialer &d): Parent(d) { HTTPMSGLOCK(arg1); }
virtual ~AnswerDialer() { HTTPMSGUNLOCK(arg1); }
+
+private:
+ AnswerDialer &operator =(const AnswerDialer &); // not implemented
};
} // namespace Adaptation
@@ -29,10 +32,8 @@
/* Initiate */
-Adaptation::Initiate::Initiate(const char *aTypeName, Initiator *anInitiator):
- AsyncJob(aTypeName), theInitiator(anInitiator)
+Adaptation::Initiate::Initiate(const char *aTypeName): AsyncJob(aTypeName)
{
- assert(theInitiator);
}
Adaptation::Initiate::~Initiate()
@@ -42,12 +43,21 @@
// can assert(!(wasStarted && theInitiator)).
}
+void
+Adaptation::Initiate::initiator(const CbcPointer &i)
+{
+ Must(!theInitiator);
+ Must(i.valid());
+ theInitiator = i;
+}
+
+
// internal cleanup
void Adaptation::Initiate::swanSong()
{
debugs(93, 5, HERE << "swan sings" << status());
- if (theInitiator) {
+ if (theInitiator.set()) {
debugs(93, 3, HERE << "fatal failure; sending abort notification");
tellQueryAborted(true); // final by default
}
@@ -57,27 +67,22 @@
void Adaptation::Initiate::clearInitiator()
{
- if (theInitiator)
- theInitiator.clear();
+ theInitiator.clear();
}
void Adaptation::Initiate::sendAnswer(HttpMsg *msg)
{
assert(msg);
- if (theInitiator.isThere()) {
- CallJob(93, 5, __FILE__, __LINE__, "Initiator::noteAdaptAnswer",
- AnswerDialer(theInitiator.ptr(), &Initiator::noteAdaptationAnswer, msg));
- }
+ CallJob(93, 5, __FILE__, __LINE__, "Initiator::noteAdaptationAnswer",
+ AnswerDialer(theInitiator, &Initiator::noteAdaptationAnswer, msg));
clearInitiator();
}
void Adaptation::Initiate::tellQueryAborted(bool final)
{
- if (theInitiator.isThere()) {
- CallJobHere1(93, 5, theInitiator.ptr(),
- Initiator::noteAdaptationQueryAbort, final);
- }
+ CallJobHere1(93, 5, theInitiator,
+ Initiator, noteAdaptationQueryAbort, final);
clearInitiator();
}
@@ -85,57 +90,3 @@
{
return AsyncJob::status(); // for now
}
-
-
-/* InitiatorHolder */
-
-Adaptation::InitiatorHolder::InitiatorHolder(Initiator *anInitiator):
- prime(0), cbdata(0)
-{
- if (anInitiator) {
- cbdata = cbdataReference(anInitiator->toCbdata());
- prime = anInitiator;
- }
-}
-
-Adaptation::InitiatorHolder::InitiatorHolder(const InitiatorHolder &anInitiator):
- prime(0), cbdata(0)
-{
- if (anInitiator != NULL && cbdataReferenceValid(anInitiator.cbdata)) {
- cbdata = cbdataReference(anInitiator.cbdata);
- prime = anInitiator.prime;
- }
-}
-
-Adaptation::InitiatorHolder::~InitiatorHolder()
-{
- clear();
-}
-
-void Adaptation::InitiatorHolder::clear()
-{
- if (prime) {
- prime = NULL;
- cbdataReferenceDone(cbdata);
- }
-}
-
-Adaptation::Initiator *Adaptation::InitiatorHolder::ptr()
-{
- assert(isThere());
- return prime;
-}
-
-bool
-Adaptation::InitiatorHolder::isThere()
-{
- return prime && cbdataReferenceValid(cbdata);
-}
-
-// should not be used
-Adaptation::InitiatorHolder &
-Adaptation::InitiatorHolder::operator =(const InitiatorHolder &anInitiator)
-{
- assert(false);
- return *this;
-}
diff -u -r -N squid-3.1.7/src/adaptation/Initiate.h squid-3.1.8/src/adaptation/Initiate.h
--- squid-3.1.7/src/adaptation/Initiate.h 2010-08-24 17:41:27.000000000 +1200
+++ squid-3.1.8/src/adaptation/Initiate.h 2010-09-04 15:25:57.000000000 +1200
@@ -1,8 +1,8 @@
#ifndef SQUID_ADAPTATION__INITIATE_H
#define SQUID_ADAPTATION__INITIATE_H
-#include "base/AsyncCall.h"
#include "base/AsyncJob.h"
+#include "base/CbcPointer.h"
#include "adaptation/forward.h"
class HttpMsg;
@@ -10,37 +10,6 @@
namespace Adaptation
{
-/* Initiator holder associtates an initiator with its cbdata. It is used as
- * a temporary hack to make cbdata work with multiple inheritance. We need
- * this hack because we cannot know whether the initiator pointer is still
- * valid without dereferencing it to call toCbdata()
- * TODO: JobDialer uses the same trick. Factor out or move this code. */
-class InitiatorHolder
-{
-public:
- InitiatorHolder(Initiator *anInitiator);
- InitiatorHolder(const InitiatorHolder &anInitiator);
- ~InitiatorHolder();
-
- void clear();
-
- // to make comparison with NULL possible
- operator void*() { return prime; }
- bool operator == (void *) const { return prime == NULL; }
- bool operator != (void *) const { return prime != NULL; }
- bool operator !() const { return !prime; }
-
- bool isThere(); // we have a valid initiator pointer
- Initiator *ptr(); // asserts isThere()
- void *theCbdata() { return cbdata;}
-
-private:
- InitiatorHolder &operator =(const InitiatorHolder &anInitiator);
-
- Initiator *prime;
- void *cbdata;
-};
-
/*
* The Initiate is a common base for queries or transactions
* initiated by an Initiator. This interface exists to allow an
@@ -56,9 +25,11 @@
{
public:
- Initiate(const char *aTypeName, Initiator *anInitiator);
+ Initiate(const char *aTypeName);
virtual ~Initiate();
+ void initiator(const CbcPointer &i); ///< sets initiator
+
// communication with the initiator
virtual void noteInitiatorAborted() = 0;
@@ -71,7 +42,7 @@
virtual const char *status() const; // for debugging
- InitiatorHolder theInitiator;
+ CbcPointer theInitiator;
private:
Initiate(const Initiate &); // no definition
diff -u -r -N squid-3.1.7/src/adaptation/Initiator.cc squid-3.1.8/src/adaptation/Initiator.cc
--- squid-3.1.7/src/adaptation/Initiator.cc 2010-08-24 17:41:26.000000000 +1200
+++ squid-3.1.8/src/adaptation/Initiator.cc 2010-09-04 15:25:57.000000000 +1200
@@ -5,27 +5,26 @@
#include "squid.h"
#include "adaptation/Initiate.h"
#include "adaptation/Initiator.h"
+#include "base/AsyncJobCalls.h"
-Adaptation::Initiate *
-Adaptation::Initiator::initiateAdaptation(Adaptation::Initiate *x)
+CbcPointer
+Adaptation::Initiator::initiateAdaptation(Initiate *x)
{
- if ((x = dynamic_cast(Initiate::AsyncStart(x))))
- x = cbdataReference(x);
- return x;
+ CbcPointer i(x);
+ x->initiator(this);
+ Start(x);
+ return i;
}
void
-Adaptation::Initiator::clearAdaptation(Initiate *&x)
+Adaptation::Initiator::clearAdaptation(CbcPointer &x)
{
- assert(x);
- cbdataReferenceDone(x);
+ x.clear();
}
void
-Adaptation::Initiator::announceInitiatorAbort(Initiate *&x)
+Adaptation::Initiator::announceInitiatorAbort(CbcPointer &x)
{
- if (x) {
- CallJobHere(93, 5, x, Initiate::noteInitiatorAborted);
- clearAdaptation(x);
- }
+ CallJobHere(93, 5, x, Initiate, noteInitiatorAborted);
+ clearAdaptation(x);
}
diff -u -r -N squid-3.1.7/src/adaptation/Initiator.h squid-3.1.8/src/adaptation/Initiator.h
--- squid-3.1.7/src/adaptation/Initiator.h 2010-08-24 17:41:27.000000000 +1200
+++ squid-3.1.8/src/adaptation/Initiator.h 2010-09-04 15:25:57.000000000 +1200
@@ -2,6 +2,7 @@
#define SQUID_ADAPTATION__INITIATOR_H
#include "base/AsyncJob.h"
+#include "base/CbcPointer.h"
#include "adaptation/forward.h"
/*
@@ -32,13 +33,17 @@
virtual void noteAdaptationQueryAbort(bool final) = 0;
protected:
- Initiate *initiateAdaptation(Initiate *x); // locks and returns x
+ ///< starts freshly created initiate and returns a safe pointer to it
+ CbcPointer initiateAdaptation(Initiate *x);
- // done with x (and not calling announceInitiatorAbort)
- void clearAdaptation(Initiate *&x); // unlocks x
+ /// clears the pointer (does not call announceInitiatorAbort)
+ void clearAdaptation(CbcPointer &x);
- // inform the transaction about abnormal termination and clear it
- void announceInitiatorAbort(Initiate *&x); // unlocks x
+ /// inform the transaction about abnormal termination and clear the pointer
+ void announceInitiatorAbort(CbcPointer &x);
+
+ /// Must(initiated(initiate)) instead of Must(initiate.set()), for clarity
+ bool initiated(const CbcPointer &job) const { return job.set(); }
};
} // namespace Adaptation
diff -u -r -N squid-3.1.7/src/adaptation/Iterator.cc squid-3.1.8/src/adaptation/Iterator.cc
--- squid-3.1.7/src/adaptation/Iterator.cc 2010-08-24 17:41:27.000000000 +1200
+++ squid-3.1.8/src/adaptation/Iterator.cc 2010-09-04 15:25:57.000000000 +1200
@@ -14,11 +14,11 @@
#include "adaptation/ServiceGroups.h"
-Adaptation::Iterator::Iterator(Adaptation::Initiator *anInitiator,
- HttpMsg *aMsg, HttpRequest *aCause,
- const ServiceGroupPointer &aGroup):
+Adaptation::Iterator::Iterator(
+ HttpMsg *aMsg, HttpRequest *aCause,
+ const ServiceGroupPointer &aGroup):
AsyncJob("Iterator"),
- Adaptation::Initiate("Iterator", anInitiator),
+ Adaptation::Initiate("Iterator"),
theGroup(aGroup),
theMsg(HTTPMSGLOCK(aMsg)),
theCause(aCause ? HTTPMSGLOCK(aCause) : NULL),
@@ -69,8 +69,8 @@
debugs(93,5, HERE << "using adaptation service: " << service->cfg().key);
theLauncher = initiateAdaptation(
- service->makeXactLauncher(this, theMsg, theCause));
- Must(theLauncher);
+ service->makeXactLauncher(theMsg, theCause));
+ Must(initiated(theLauncher));
Must(!done());
}
@@ -148,10 +148,10 @@
void Adaptation::Iterator::swanSong()
{
- if (theInitiator)
+ if (theInitiator.set())
tellQueryAborted(true); // abnormal condition that should not happen
- if (theLauncher)
+ if (initiated(theLauncher))
clearAdaptation(theLauncher);
Adaptation::Initiate::swanSong();
diff -u -r -N squid-3.1.7/src/adaptation/Iterator.h squid-3.1.8/src/adaptation/Iterator.h
--- squid-3.1.7/src/adaptation/Iterator.h 2010-08-24 17:41:26.000000000 +1200
+++ squid-3.1.8/src/adaptation/Iterator.h 2010-09-04 15:25:57.000000000 +1200
@@ -21,8 +21,7 @@
class Iterator: public Initiate, public Initiator
{
public:
- Iterator(Adaptation::Initiator *anInitiator,
- HttpMsg *virginHeader, HttpRequest *virginCause,
+ Iterator(HttpMsg *virginHeader, HttpRequest *virginCause,
const Adaptation::ServiceGroupPointer &aGroup);
virtual ~Iterator();
@@ -52,7 +51,7 @@
ServicePlan thePlan; ///< which services to use and in what order
HttpMsg *theMsg; ///< the message being adapted (virgin for each step)
HttpRequest *theCause; ///< the cause of the original virgin message
- Adaptation::Initiate *theLauncher; ///< current transaction launcher
+ CbcPointer theLauncher; ///< current transaction launcher
int iterations; ///< number of steps initiated
bool adapted; ///< whether the virgin message has been replaced
diff -u -r -N squid-3.1.7/src/adaptation/Makefile.am squid-3.1.8/src/adaptation/Makefile.am
--- squid-3.1.7/src/adaptation/Makefile.am 2010-08-24 17:41:27.000000000 +1200
+++ squid-3.1.8/src/adaptation/Makefile.am 2010-09-04 15:25:57.000000000 +1200
@@ -12,11 +12,6 @@
SUBDIRS += ecap
endif
-if USE_LOADABLE_MODULES
-## LTDL headers require their local include path...
-INCLUDES += $(INCLTDL)
-endif
-
noinst_LTLIBRARIES = libadaptation.la
## start with the code shared among all adaptation schemes
diff -u -r -N squid-3.1.7/src/adaptation/Makefile.in squid-3.1.8/src/adaptation/Makefile.in
--- squid-3.1.7/src/adaptation/Makefile.in 2010-08-24 17:42:38.000000000 +1200
+++ squid-3.1.8/src/adaptation/Makefile.in 2010-09-04 15:26:27.000000000 +1200
@@ -35,9 +35,9 @@
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(top_srcdir)/src/Common.am $(top_srcdir)/src/TestHeaders.am
check_PROGRAMS =
-@USE_ICAP_CLIENT_TRUE@am__append_1 = icap
-@USE_ECAP_TRUE@am__append_2 = ecap
-@USE_LOADABLE_MODULES_TRUE@am__append_3 = $(INCLTDL)
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
+@USE_ICAP_CLIENT_TRUE@am__append_2 = icap
+@USE_ECAP_TRUE@am__append_3 = ecap
subdir = src/adaptation
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
@@ -291,8 +291,8 @@
CLEANFILES = testHeaders
TESTS = testHeaders
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_3)
-SUBDIRS = $(am__append_1) $(am__append_2)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1)
+SUBDIRS = $(am__append_2) $(am__append_3)
noinst_LTLIBRARIES = libadaptation.la
libadaptation_la_SOURCES = \
AccessCheck.cc \
diff -u -r -N squid-3.1.7/src/adaptation/Service.h squid-3.1.8/src/adaptation/Service.h
--- squid-3.1.7/src/adaptation/Service.h 2010-08-24 17:41:25.000000000 +1200
+++ squid-3.1.8/src/adaptation/Service.h 2010-09-04 15:25:57.000000000 +1200
@@ -31,7 +31,7 @@
virtual bool broken() const;
virtual bool up() const = 0; // see comments above
- virtual Initiate *makeXactLauncher(Initiator *, HttpMsg *virginHeader, HttpRequest *virginCause) = 0;
+ virtual Initiate *makeXactLauncher(HttpMsg *virginHeader, HttpRequest *virginCause) = 0;
typedef void Callback(void *data, Pointer &service);
void callWhenReady(Callback *cb, void *data);
diff -u -r -N squid-3.1.7/src/auth/Makefile.in squid-3.1.8/src/auth/Makefile.in
--- squid-3.1.7/src/auth/Makefile.in 2010-08-24 17:42:39.000000000 +1200
+++ squid-3.1.8/src/auth/Makefile.in 2010-09-04 15:26:28.000000000 +1200
@@ -35,6 +35,7 @@
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(top_srcdir)/src/Common.am
check_PROGRAMS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
subdir = src/auth
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
@@ -295,7 +296,8 @@
CLEANFILES = testHeaders
TESTS = testHeaders
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir)
noinst_LTLIBRARIES = libauth.la libacls.la $(AUTH_LIBS_TO_BUILD)
EXTRA_LTLIBRARIES = libbasic.la libdigest.la libntlm.la libnegotiate.la
libauth_la_SOURCES = \
diff -u -r -N squid-3.1.7/src/base/AsyncJobCalls.h squid-3.1.8/src/base/AsyncJobCalls.h
--- squid-3.1.7/src/base/AsyncJobCalls.h 2010-08-24 17:41:27.000000000 +1200
+++ squid-3.1.8/src/base/AsyncJobCalls.h 2010-09-04 15:25:57.000000000 +1200
@@ -7,6 +7,66 @@
#define SQUID_ASYNCJOBCALLS_H
#include "base/AsyncJob.h"
+#include "base/CbcPointer.h"
+
+/**
+ \ingroup AsyncJobAPI
+ * This is a base class for all job call dialers. It does all the job
+ * dialing logic (debugging, handling exceptions, etc.) except for calling
+ * the job method. The latter requires knowing the number and type of method
+ * parameters. Thus, we add a dial() virtual method that the MemFunT templates
+ * below implement for us, calling the job's method with the right params.
+ */
+template
+class JobDialer: public CallDialer
+{
+public:
+ typedef Job DestClass;
+ typedef CbcPointer JobPointer;
+
+ JobDialer(const JobPointer &aJob);
+ JobDialer(const JobDialer &d);
+
+ virtual bool canDial(AsyncCall &call);
+ void dial(AsyncCall &call);
+
+ JobPointer job;
+
+protected:
+ virtual void doDial() = 0; // actually calls the job method
+
+private:
+ // not implemented and should not be needed
+ JobDialer &operator =(const JobDialer &);
+};
+
+/// schedule an async job call using a dialer; use CallJobHere macros instead
+template
+bool
+CallJob(int debugSection, int debugLevel, const char *fileName, int fileLine,
+ const char *callName, const Dialer &dialer)
+{
+ AsyncCall::Pointer call = asyncCall(debugSection, debugLevel, callName, dialer);
+ return ScheduleCall(fileName, fileLine, call);
+}
+
+
+#define CallJobHere(debugSection, debugLevel, job, Class, method) \
+ CallJob((debugSection), (debugLevel), __FILE__, __LINE__, \
+ (#Class "::" #method), \
+ JobMemFun((job), &Class::method))
+
+#define CallJobHere1(debugSection, debugLevel, job, Class, method, arg1) \
+ CallJob((debugSection), (debugLevel), __FILE__, __LINE__, \
+ (#Class "::" #method), \
+ JobMemFun((job), &Class::method, (arg1)))
+
+
+/// Convenience macro to create a Dialer-based job callback
+#define JobCallback(dbgSection, dbgLevel, Dialer, job, method) \
+ asyncCall((dbgSection), (dbgLevel), #method, \
+ Dialer(CbcPointer(job), &method))
+
/*
* *MemFunT are member function (i.e., class method) wrappers. They store
@@ -24,42 +84,40 @@
// Arity names are from http://en.wikipedia.org/wiki/Arity
-template
-class NullaryMemFunT: public JobDialer
+template
+class NullaryMemFunT: public JobDialer
{
public:
- typedef void (C::*Method)();
- explicit NullaryMemFunT(C *anObject, Method aMethod):
- JobDialer(anObject), object(anObject), method(aMethod) {}
+ typedef void (Job::*Method)();
+ explicit NullaryMemFunT(const CbcPointer &aJob, Method aMethod):
+ JobDialer(aJob), method(aMethod) {}
virtual void print(std::ostream &os) const { os << "()"; }
public:
- C *object;
Method method;
protected:
- virtual void doDial() { (object->*method)(); }
+ virtual void doDial() { ((&(*this->job))->*method)(); }
};
-template
-class UnaryMemFunT: public JobDialer
+template
+class UnaryMemFunT: public JobDialer
{
public:
- typedef void (C::*Method)(Argument1);
- explicit UnaryMemFunT(C *anObject, Method aMethod, const Argument1 &anArg1):
- JobDialer(anObject),
- object(anObject), method(aMethod), arg1(anArg1) {}
+ typedef void (Job::*Method)(Argument1);
+ explicit UnaryMemFunT(const CbcPointer &aJob, Method aMethod,
+ const Argument1 &anArg1): JobDialer(aJob),
+ method(aMethod), arg1(anArg1) {}
virtual void print(std::ostream &os) const { os << '(' << arg1 << ')'; }
public:
- C *object;
Method method;
Argument1 arg1;
protected:
- virtual void doDial() { (object->*method)(arg1); }
+ virtual void doDial() { ((&(*this->job))->*method)(arg1); }
};
// ... add more as needed
@@ -71,17 +129,57 @@
template
NullaryMemFunT
-MemFun(C *object, typename NullaryMemFunT::Method method)
+JobMemFun(const CbcPointer &job, typename NullaryMemFunT::Method method)
{
- return NullaryMemFunT(object, method);
+ return NullaryMemFunT(job, method);
}
template
UnaryMemFunT
-MemFun(C *object, typename UnaryMemFunT::Method method,
- Argument1 arg1)
+JobMemFun(const CbcPointer &job, typename UnaryMemFunT::Method method,
+ Argument1 arg1)
+{
+ return UnaryMemFunT(job, method, arg1);
+}
+
+
+// inlined methods
+
+template
+JobDialer::JobDialer(const JobPointer &aJob): job(aJob)
+{
+}
+
+template
+JobDialer::JobDialer(const JobDialer &d): CallDialer(d), job(d.job)
{
- return UnaryMemFunT(object, method, arg1);
+}
+
+template
+bool
+JobDialer::canDial(AsyncCall &call)
+{
+ if (!job)
+ return call.cancel("job gone");
+
+ return job->canBeCalled(call);
+}
+
+template
+void
+JobDialer::dial(AsyncCall &call)
+{
+ job->callStart(call);
+
+ try {
+ doDial();
+ } catch (const std::exception &e) {
+ debugs(call.debugSection, 3,
+ HERE << call.name << " threw exception: " << e.what());
+ job->callException(e);
+ }
+
+ job->callEnd(); // may delete job
}
#endif /* SQUID_ASYNCJOBCALLS_H */
diff -u -r -N squid-3.1.7/src/base/AsyncJob.cc squid-3.1.8/src/base/AsyncJob.cc
--- squid-3.1.7/src/base/AsyncJob.cc 2010-08-24 17:41:26.000000000 +1200
+++ squid-3.1.8/src/base/AsyncJob.cc 2010-09-04 15:25:57.000000000 +1200
@@ -3,6 +3,7 @@
*/
#include "squid.h"
+#include "base/AsyncJobCalls.h"
#include "cbdata.h"
#include "MemBuf.h"
#include "TextException.h"
@@ -12,10 +13,10 @@
unsigned int AsyncJob::TheLastId = 0;
-AsyncJob *AsyncJob::AsyncStart(AsyncJob *job)
+AsyncJob::Pointer AsyncJob::Start(AsyncJob *j)
{
- assert(job);
- CallJobHere(93, 5, job, AsyncJob::noteStart);
+ AsyncJob::Pointer job(j);
+ CallJobHere(93, 5, job, AsyncJob, start);
return job;
}
@@ -29,11 +30,6 @@
{
}
-void AsyncJob::noteStart()
-{
- start();
-}
-
void AsyncJob::start()
{
}
@@ -52,8 +48,9 @@
// there is no call wrapper waiting for our return, so we fake it
debugs(93, 5, typeName << " will delete this, reason: " << stopReason);
+ CbcPointer self(this);
AsyncCall::Pointer fakeCall = asyncCall(93,4, "FAKE-deleteThis",
- MemFun(this, &AsyncJob::deleteThis, aReason));
+ JobMemFun(self, &AsyncJob::deleteThis, aReason));
inCall = fakeCall;
callEnd();
// delete fakeCall;
@@ -164,60 +161,3 @@
}
-/* JobDialer */
-
-JobDialer::JobDialer(AsyncJob *aJob): job(NULL), lock(NULL)
-{
- if (aJob) {
- lock = cbdataReference(aJob->toCbdata());
- job = aJob;
- }
-}
-
-JobDialer::JobDialer(const JobDialer &d): CallDialer(d),
- job(NULL), lock(NULL)
-{
- if (d.lock && cbdataReferenceValid(d.lock)) {
- lock = cbdataReference(d.lock);
- Must(d.job);
- job = d.job;
- }
-}
-
-JobDialer::~JobDialer()
-{
- cbdataReferenceDone(lock); // lock may be NULL
-}
-
-
-bool
-JobDialer::canDial(AsyncCall &call)
-{
- if (!lock)
- return call.cancel("job was gone before the call");
-
- if (!cbdataReferenceValid(lock))
- return call.cancel("job gone after the call");
-
- Must(job);
- return job->canBeCalled(call);
-}
-
-void
-JobDialer::dial(AsyncCall &call)
-{
- Must(lock && cbdataReferenceValid(lock)); // canDial() checks for this
- Must(job);
-
- job->callStart(call);
-
- try {
- doDial();
- } catch (const std::exception &e) {
- debugs(call.debugSection, 3,
- HERE << call.name << " threw exception: " << e.what());
- job->callException(e);
- }
-
- job->callEnd(); // may delete job
-}
diff -u -r -N squid-3.1.7/src/base/AsyncJob.h squid-3.1.8/src/base/AsyncJob.h
--- squid-3.1.7/src/base/AsyncJob.h 2010-08-24 17:41:26.000000000 +1200
+++ squid-3.1.8/src/base/AsyncJob.h 2010-09-04 15:25:57.000000000 +1200
@@ -8,6 +8,9 @@
#include "base/AsyncCall.h"
#include "TextException.h"
+template
+class CbcPointer;
+
/**
\defgroup AsyncJobAPI Async-Jobs API
\par
@@ -29,17 +32,20 @@
*/
/// \ingroup AsyncJobAPI
+/// Base class for all asynchronous jobs
class AsyncJob
{
-
public:
- static AsyncJob *AsyncStart(AsyncJob *job); // use this to start jobs
+ typedef CbcPointer Pointer;
+public:
AsyncJob(const char *aTypeName);
virtual ~AsyncJob();
virtual void *toCbdata() = 0;
- void noteStart(); // calls virtual start
+
+ /// starts a freshly created job (i.e., makes the job asynchronous)
+ static Pointer Start(AsyncJob *job);
protected:
// XXX: temporary method to replace "delete this" in jobs-in-transition.
@@ -72,56 +78,4 @@
static unsigned int TheLastId;
};
-
-/**
- \ingroup AsyncJobAPI
- * This is a base class for all job call dialers. It does all the job
- * dialing logic (debugging, handling exceptions, etc.) except for calling
- * the job method. The latter is not possible without templates and we
- * want to keep this class simple and template-free. Thus, we add a dial()
- * virtual method that the JobCallT template below will implement for us,
- * calling the job.
- */
-class JobDialer: public CallDialer
-{
-public:
- JobDialer(AsyncJob *aJob);
- JobDialer(const JobDialer &d);
- virtual ~JobDialer();
-
- virtual bool canDial(AsyncCall &call);
- void dial(AsyncCall &call);
-
- AsyncJob *job;
- void *lock; // job's cbdata
-
-protected:
- virtual void doDial() = 0; // actually calls the job method
-
-private:
- // not implemented and should not be needed
- JobDialer &operator =(const JobDialer &);
-};
-
-#include "base/AsyncJobCalls.h"
-
-template
-bool
-CallJob(int debugSection, int debugLevel, const char *fileName, int fileLine,
- const char *callName, const Dialer &dialer)
-{
- AsyncCall::Pointer call = asyncCall(debugSection, debugLevel, callName, dialer);
- return ScheduleCall(fileName, fileLine, call);
-}
-
-
-#define CallJobHere(debugSection, debugLevel, job, method) \
- CallJob((debugSection), (debugLevel), __FILE__, __LINE__, #method, \
- MemFun((job), &method))
-
-#define CallJobHere1(debugSection, debugLevel, job, method, arg1) \
- CallJob((debugSection), (debugLevel), __FILE__, __LINE__, #method, \
- MemFun((job), &method, (arg1)))
-
-
#endif /* SQUID_ASYNC_JOB_H */
diff -u -r -N squid-3.1.7/src/base/CbcPointer.h squid-3.1.8/src/base/CbcPointer.h
--- squid-3.1.7/src/base/CbcPointer.h 1970-01-01 12:00:00.000000000 +1200
+++ squid-3.1.8/src/base/CbcPointer.h 2010-09-04 15:25:58.000000000 +1200
@@ -0,0 +1,162 @@
+/*
+ * $Id$
+ */
+
+#ifndef SQUID_CBC_POINTER_H
+#define SQUID_CBC_POINTER_H
+
+#include "TextException.h"
+#include "cbdata.h"
+
+/**
+ \ingroup CBDATAAPI
+ *
+ * Safely points to a cbdata-protected class (cbc), such as an AsyncJob.
+ * When a cbc we communicate with disappears without
+ * notice or a notice has not reached us yet, this class prevents
+ * dereferencing the pointer to the gone cbc object.
+ */
+template
+class CbcPointer
+{
+public:
+ CbcPointer(); // a nil pointer
+ CbcPointer(Cbc *aCbc);
+ CbcPointer(const CbcPointer &p);
+ ~CbcPointer();
+
+ Cbc *raw() const; ///< a temporary raw Cbc pointer; may be invalid
+ Cbc *get() const; ///< a temporary valid raw Cbc pointer or NULL
+ Cbc &operator *() const; ///< a valid Cbc reference or exception
+ Cbc *operator ->() const; ///< a valid Cbc pointer or exception
+
+ // no bool operator because set() != valid()
+ bool set() const { return cbc != NULL; } ///< was set but may be invalid
+ Cbc *valid() const { return get(); } ///< was set and is valid
+ bool operator !() const { return !valid(); } ///< invalid or was not set
+ bool operator ==(const CbcPointer &o) const { return lock == o.lock; }
+
+ CbcPointer &operator =(const CbcPointer &p);
+
+ /// support converting a child cbc pointer into a parent cbc pointer
+ template
+ CbcPointer(const CbcPointer &o): cbc(o.raw()), lock(NULL) {
+ if (o.valid())
+ lock = cbdataReference(o->toCbdata());
+ }
+
+ /// support assigning a child cbc pointer to a parent cbc pointer
+ template
+ CbcPointer &operator =(const CbcPointer &o) {
+ if (this != &o) { // assignment to self
+ clear();
+ cbc = o.raw(); // so that set() is accurate
+ if (o.valid())
+ lock = cbdataReference(o->toCbdata());
+ }
+ return *this;
+ }
+
+ void clear(); ///< make pointer not set; does not invalidate cbdata
+
+ std::ostream &print(std::ostream &os) const;
+
+private:
+ Cbc *cbc; // a possibly invalid pointer to a cbdata class
+ void *lock; // a valid pointer to cbc's cbdata or nil
+};
+
+template
+inline
+std::ostream &operator <<(std::ostream &os, const CbcPointer &p)
+{
+ return p.print(os);
+}
+
+// inlined methods
+
+template
+CbcPointer::CbcPointer(): cbc(NULL), lock(NULL)
+{
+}
+
+template
+CbcPointer::CbcPointer(Cbc *aCbc): cbc(aCbc), lock(NULL)
+{
+ if (cbc)
+ lock = cbdataReference(cbc->toCbdata());
+}
+
+template
+CbcPointer::CbcPointer(const CbcPointer &d): cbc(d.cbc), lock(NULL)
+{
+ if (d.lock && cbdataReferenceValid(d.lock))
+ lock = cbdataReference(d.lock);
+}
+
+template
+CbcPointer::~CbcPointer()
+{
+ clear();
+}
+
+template
+CbcPointer &CbcPointer::operator =(const CbcPointer &d)
+{
+ if (this != &d) { // assignment to self
+ clear();
+ cbc = d.cbc;
+ if (d.lock && cbdataReferenceValid(d.lock))
+ lock = cbdataReference(d.lock);
+ }
+ return *this;
+}
+
+template
+void
+CbcPointer::clear()
+{
+ cbdataReferenceDone(lock); // lock may be nil before and will be nil after
+ cbc = NULL;
+}
+
+template
+Cbc *
+CbcPointer::raw() const
+{
+ return cbc;
+}
+
+template
+Cbc *
+CbcPointer::get() const
+{
+ return (lock && cbdataReferenceValid(lock)) ? cbc : NULL;
+}
+
+template
+Cbc &
+CbcPointer::operator *() const
+{
+ Cbc *c = get();
+ Must(c);
+ return *c;
+}
+
+template
+Cbc *
+CbcPointer::operator ->() const
+{
+ Cbc *c = get();
+ Must(c);
+ return c;
+}
+
+template
+std::ostream &CbcPointer::print(std::ostream &os) const
+{
+ return os << cbc << '/' << lock;
+}
+
+
+#endif /* SQUID_CBC_POINTER_H */
diff -u -r -N squid-3.1.7/src/base/Makefile.am squid-3.1.8/src/base/Makefile.am
--- squid-3.1.7/src/base/Makefile.am 2010-08-24 17:41:27.000000000 +1200
+++ squid-3.1.8/src/base/Makefile.am 2010-09-04 15:25:57.000000000 +1200
@@ -11,4 +11,5 @@
AsyncJob.cc \
AsyncJobCalls.h \
AsyncCallQueue.cc \
- AsyncCallQueue.h
+ AsyncCallQueue.h \
+ CbcPointer.h
diff -u -r -N squid-3.1.7/src/base/Makefile.in squid-3.1.8/src/base/Makefile.in
--- squid-3.1.7/src/base/Makefile.in 2010-08-24 17:42:39.000000000 +1200
+++ squid-3.1.8/src/base/Makefile.in 2010-09-04 15:26:28.000000000 +1200
@@ -35,6 +35,7 @@
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(top_srcdir)/src/Common.am $(top_srcdir)/src/TestHeaders.am
check_PROGRAMS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
subdir = src/base
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
@@ -274,13 +275,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES = testHeaders
TESTS = testHeaders
-INCLUDES = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/include \
- -I$(top_srcdir)/src \
- -I$(top_builddir)/include \
- $(SQUID_CPPUNIT_INC)
-
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1)
noinst_LTLIBRARIES = libbase.la
libbase_la_SOURCES = \
AsyncCall.cc \
@@ -289,7 +285,8 @@
AsyncJob.cc \
AsyncJobCalls.h \
AsyncCallQueue.cc \
- AsyncCallQueue.h
+ AsyncCallQueue.h \
+ CbcPointer.h
all: all-am
diff -u -r -N squid-3.1.7/src/BodyPipe.cc squid-3.1.8/src/BodyPipe.cc
--- squid-3.1.7/src/BodyPipe.cc 2010-08-24 17:41:25.000000000 +1200
+++ squid-3.1.8/src/BodyPipe.cc 2010-09-04 15:25:58.000000000 +1200
@@ -1,5 +1,6 @@
#include "squid.h"
+#include "base/AsyncJobCalls.h"
#include "BodyPipe.h"
#include "TextException.h"
@@ -40,8 +41,9 @@
public:
typedef UnaryMemFunT Parent;
- BodyProducerDialer(BodyProducer *aProducer, Parent::Method aHandler,
- BodyPipe::Pointer bp): Parent(aProducer, aHandler, bp) {}
+ BodyProducerDialer(const BodyProducer::Pointer &aProducer,
+ Parent::Method aHandler, BodyPipe::Pointer bp):
+ Parent(aProducer, aHandler, bp) {}
virtual bool canDial(AsyncCall &call);
};
@@ -54,8 +56,9 @@
public:
typedef UnaryMemFunT Parent;
- BodyConsumerDialer(BodyConsumer *aConsumer, Parent::Method aHandler,
- BodyPipe::Pointer bp): Parent(aConsumer, aHandler, bp) {}
+ BodyConsumerDialer(const BodyConsumer::Pointer &aConsumer,
+ Parent::Method aHandler, BodyPipe::Pointer bp):
+ Parent(aConsumer, aHandler, bp) {}
virtual bool canDial(AsyncCall &call);
};
@@ -66,7 +69,7 @@
if (!Parent::canDial(call))
return false;
- BodyProducer *producer = object;
+ const BodyProducer::Pointer &producer = job;
BodyPipe::Pointer pipe = arg1;
if (!pipe->stillProducing(producer)) {
debugs(call.debugSection, call.debugLevel, HERE << producer <<
@@ -83,7 +86,7 @@
if (!Parent::canDial(call))
return false;
- BodyConsumer *consumer = object;
+ const BodyConsumer::Pointer &consumer = job;
BodyPipe::Pointer pipe = arg1;
if (!pipe->stillConsuming(consumer)) {
debugs(call.debugSection, call.debugLevel, HERE << consumer <<
@@ -183,9 +186,9 @@
void
BodyPipe::clearProducer(bool atEof)
{
- if (theProducer) {
+ if (theProducer.set()) {
debugs(91,7, HERE << "clearing BodyPipe producer" << status());
- theProducer = NULL;
+ theProducer.clear();
if (atEof) {
if (!bodySizeKnown())
theBodySize = thePutSize;
@@ -215,10 +218,10 @@
}
bool
-BodyPipe::setConsumerIfNotLate(Consumer *aConsumer)
+BodyPipe::setConsumerIfNotLate(const Consumer::Pointer &aConsumer)
{
assert(!theConsumer);
- assert(aConsumer);
+ assert(aConsumer.set()); // but might be invalid
// TODO: convert this into an exception and remove IfNotLate suffix
// If there is something consumed already, we are in an auto-consuming mode
@@ -247,9 +250,9 @@
void
BodyPipe::clearConsumer()
{
- if (theConsumer) {
+ if (theConsumer.set()) {
debugs(91,7, HERE << "clearing consumer" << status());
- theConsumer = NULL;
+ theConsumer.clear();
if (consumedSize() && !exhausted()) {
AsyncCall::Pointer call= asyncCall(91, 7,
"BodyProducer::noteBodyConsumerAborted",
@@ -377,7 +380,7 @@
void
BodyPipe::scheduleBodyDataNotification()
{
- if (theConsumer) {
+ if (theConsumer.valid()) { // TODO: allow asyncCall() to check this instead
AsyncCall::Pointer call = asyncCall(91, 7,
"BodyConsumer::noteMoreBodyDataAvailable",
BodyConsumerDialer(theConsumer,
@@ -389,7 +392,7 @@
void
BodyPipe::scheduleBodyEndNotification()
{
- if (theConsumer) {
+ if (theConsumer.valid()) { // TODO: allow asyncCall() to check this instead
if (bodySizeKnown() && bodySize() == thePutSize) {
AsyncCall::Pointer call = asyncCall(91, 7,
"BodyConsumer::noteBodyProductionEnded",
@@ -423,10 +426,10 @@
outputBuffer.Printf(" %d+%d", (int)theBuf.contentSize(), (int)theBuf.spaceSize());
outputBuffer.Printf(" pipe%p", this);
- if (theProducer)
- outputBuffer.Printf(" prod%p", theProducer);
- if (theConsumer)
- outputBuffer.Printf(" cons%p", theConsumer);
+ if (theProducer.set())
+ outputBuffer.Printf(" prod%p", theProducer.get());
+ if (theConsumer.set())
+ outputBuffer.Printf(" cons%p", theConsumer.get());
if (mustAutoConsume)
outputBuffer.append(" A", 2);
diff -u -r -N squid-3.1.7/src/BodyPipe.h squid-3.1.8/src/BodyPipe.h
--- squid-3.1.7/src/BodyPipe.h 2010-08-24 17:41:26.000000000 +1200
+++ squid-3.1.8/src/BodyPipe.h 2010-09-04 15:25:57.000000000 +1200
@@ -3,8 +3,8 @@
#define SQUID_BODY_PIPE_H
#include "MemBuf.h"
-#include "base/AsyncCall.h"
#include "base/AsyncJob.h"
+#include "base/CbcPointer.h"
class BodyPipe;
@@ -14,6 +14,8 @@
class BodyProducer: virtual public AsyncJob
{
public:
+ typedef CbcPointer Pointer;
+
BodyProducer():AsyncJob("BodyProducer") {}
virtual ~BodyProducer() {}
@@ -31,6 +33,8 @@
class BodyConsumer: virtual public AsyncJob
{
public:
+ typedef CbcPointer Pointer;
+
BodyConsumer():AsyncJob("BodyConsumer") {}
virtual ~BodyConsumer() {}
@@ -100,16 +104,16 @@
bool mayNeedMoreData() const { return !bodySizeKnown() || needsMoreData(); }
bool needsMoreData() const { return bodySizeKnown() && unproducedSize() > 0; }
uint64_t unproducedSize() const; // size of still unproduced data
- bool stillProducing(const Producer *producer) const { return theProducer == producer; }
+ bool stillProducing(const Producer::Pointer &producer) const { return theProducer == producer; }
// called by consumers
- bool setConsumerIfNotLate(Consumer *aConsumer);
+ bool setConsumerIfNotLate(const Consumer::Pointer &aConsumer);
void clearConsumer(); // aborts if still piping
size_t getMoreData(MemBuf &buf);
void consume(size_t size);
bool expectMoreAfter(uint64_t offset) const;
bool exhausted() const; // saw eof/abort and all data consumed
- bool stillConsuming(const Consumer *consumer) const { return theConsumer == consumer; }
+ bool stillConsuming(const Consumer::Pointer &consumer) const { return theConsumer == consumer; }
// start or continue consuming when there is no consumer
void enableAutoConsumption();
@@ -135,8 +139,8 @@
private:
int64_t theBodySize; // expected total content length, if known
- Producer *theProducer; // content producer, if any
- Consumer *theConsumer; // content consumer, if any
+ Producer::Pointer theProducer; // content producer, if any
+ Consumer::Pointer theConsumer; // content consumer, if any
uint64_t thePutSize; // ever-increasing total
uint64_t theGetSize; // ever-increasing total
diff -u -r -N squid-3.1.7/src/cf.data.pre squid-3.1.8/src/cf.data.pre
--- squid-3.1.7/src/cf.data.pre 2010-08-24 17:41:26.000000000 +1200
+++ squid-3.1.8/src/cf.data.pre 2010-09-04 15:25:57.000000000 +1200
@@ -1314,8 +1314,8 @@
Example where normal_service_net uses the TOS value 0x00
and good_service_net uses 0x20
- acl normal_service_net src 10.0.0.0/255.255.255.0
- acl good_service_net src 10.0.1.0/255.255.255.0
+ acl normal_service_net src 10.0.0.0/24
+ acl good_service_net src 10.0.1.0/24
tcp_outgoing_tos 0x00 normal_service_net
tcp_outgoing_tos 0x20 good_service_net
@@ -1325,8 +1325,8 @@
The TOS/DSCP byte must be exactly that - a octet value 0 - 255, or
"default" to use whatever default your host has. Note that in
- practice often only values 0 - 63 is usable as the two highest bits
- have been redefined for use by ECN (RFC3168).
+ practice often only multiples of 4 is usable as the two rightmost bits
+ have been redefined for use by ECN (RFC 3168 section 23.1).
Processing proceeds in the order specified, and stops at first fully
matching line.
diff -u -r -N squid-3.1.7/src/client_side.cc squid-3.1.8/src/client_side.cc
--- squid-3.1.7/src/client_side.cc 2010-08-24 17:41:27.000000000 +1200
+++ squid-3.1.8/src/client_side.cc 2010-09-04 15:25:57.000000000 +1200
@@ -210,8 +210,8 @@
makeSpaceAvailable();
typedef CommCbMemFunT Dialer;
- reader = asyncCall(33, 5, "ConnStateData::clientReadRequest",
- Dialer(this, &ConnStateData::clientReadRequest));
+ reader = JobCallback(33, 5,
+ Dialer, this, ConnStateData::clientReadRequest);
comm_read(fd, in.addressToReadInto(), getAvailableBufferLength(), reader);
}
@@ -1358,8 +1358,8 @@
* Set the timeout BEFORE calling clientReadRequest().
*/
typedef CommCbMemFunT TimeoutDialer;
- AsyncCall::Pointer timeoutCall = asyncCall(33, 5, "ConnStateData::requestTimeout",
- TimeoutDialer(this, &ConnStateData::requestTimeout));
+ AsyncCall::Pointer timeoutCall = JobCallback(33, 5,
+ TimeoutDialer, this, ConnStateData::requestTimeout);
commSetTimeout(fd, Config.Timeout.persistent_request, timeoutCall);
readSomeData();
@@ -1910,8 +1910,7 @@
if (!request.parseHeader(HttpParserHdrBuf(hp), HttpParserHdrSz(hp)))
return false;
- return request.header.has(HDR_TRANSFER_ENCODING) &&
- request.header.hasListMember(HDR_TRANSFER_ENCODING, "chunked", ',');
+ return request.header.chunked();
}
@@ -2313,6 +2312,7 @@
bool notedUseOfBuffer = false;
bool tePresent = false;
bool deChunked = false;
+ bool mustReplyToOptions = false;
bool unsupportedTe = false;
/* We have an initial client stream in place should it be needed */
@@ -2425,8 +2425,12 @@
} else
conn->cleanDechunkingRequest();
+ if (method == METHOD_TRACE || method == METHOD_OPTIONS)
+ request->max_forwards = request->header.getInt64(HDR_MAX_FORWARDS);
+
+ mustReplyToOptions = (method == METHOD_OPTIONS) && (request->max_forwards == 0);
unsupportedTe = tePresent && !deChunked;
- if (!urlCheckRequest(request) || unsupportedTe) {
+ if (!urlCheckRequest(request) || mustReplyToOptions || unsupportedTe) {
clientStreamNode *node = context->getClientReplyContext();
clientReplyContext *repContext = dynamic_cast(node->data.getRaw());
assert (repContext);
@@ -2928,8 +2932,8 @@
* if we don't close() here, we still need a timeout handler!
*/
typedef CommCbMemFunT TimeoutDialer;
- AsyncCall::Pointer timeoutCall = asyncCall(33, 5, "ConnStateData::requestTimeout",
- TimeoutDialer(this,&ConnStateData::requestTimeout));
+ AsyncCall::Pointer timeoutCall = JobCallback(33, 5,
+ TimeoutDialer, this, ConnStateData::requestTimeout);
commSetTimeout(io.fd, 30, timeoutCall);
/*
@@ -3055,16 +3059,16 @@
connState = connStateCreate(&details->peer, &details->me, newfd, s);
typedef CommCbMemFunT Dialer;
- AsyncCall::Pointer call = asyncCall(33, 5, "ConnStateData::connStateClosed",
- Dialer(connState, &ConnStateData::connStateClosed));
+ AsyncCall::Pointer call = JobCallback(33, 5,
+ Dialer, connState, ConnStateData::connStateClosed);
comm_add_close_handler(newfd, call);
if (Config.onoff.log_fqdn)
fqdncache_gethostbyaddr(details->peer, FQDN_LOOKUP_IF_MISS);
typedef CommCbMemFunT TimeoutDialer;
- AsyncCall::Pointer timeoutCall = asyncCall(33, 5, "ConnStateData::requestTimeout",
- TimeoutDialer(connState,&ConnStateData::requestTimeout));
+ AsyncCall::Pointer timeoutCall = JobCallback(33, 5,
+ TimeoutDialer, connState, ConnStateData::requestTimeout);
commSetTimeout(newfd, Config.Timeout.read, timeoutCall);
#if USE_IDENT
@@ -3266,16 +3270,16 @@
ConnStateData *connState = connStateCreate(details->peer, details->me,
newfd, &s->http);
typedef CommCbMemFunT Dialer;
- AsyncCall::Pointer call = asyncCall(33, 5, "ConnStateData::connStateClosed",
- Dialer(connState, &ConnStateData::connStateClosed));
+ AsyncCall::Pointer call = JobCallback(33, 5,
+ Dialer, connState, ConnStateData::connStateClosed);
comm_add_close_handler(newfd, call);
if (Config.onoff.log_fqdn)
fqdncache_gethostbyaddr(details->peer, FQDN_LOOKUP_IF_MISS);
typedef CommCbMemFunT TimeoutDialer;
- AsyncCall::Pointer timeoutCall = asyncCall(33, 5, "ConnStateData::requestTimeout",
- TimeoutDialer(connState,&ConnStateData::requestTimeout));
+ AsyncCall::Pointer timeoutCall = JobCallback(33, 5,
+ TimeoutDialer, connState, ConnStateData::requestTimeout);
commSetTimeout(newfd, Config.Timeout.request, timeoutCall);
#if USE_IDENT
@@ -3798,8 +3802,8 @@
fd_note(pinning_fd, desc);
typedef CommCbMemFunT Dialer;
- pinning.closeHandler = asyncCall(33, 5, "ConnStateData::clientPinnedConnectionClosed",
- Dialer(this, &ConnStateData::clientPinnedConnectionClosed));
+ pinning.closeHandler = JobCallback(33, 5,
+ Dialer, this, ConnStateData::clientPinnedConnectionClosed);
comm_add_close_handler(pinning_fd, pinning.closeHandler);
}
diff -u -r -N squid-3.1.7/src/client_side_reply.cc squid-3.1.8/src/client_side_reply.cc
--- squid-3.1.7/src/client_side_reply.cc 2010-08-24 17:41:27.000000000 +1200
+++ squid-3.1.8/src/client_side_reply.cc 2010-09-04 15:25:57.000000000 +1200
@@ -1391,7 +1391,6 @@
request->flags.proxy_keepalive = 0;
}
-
/* Append VIA */
if (Config.onoff.via) {
LOCAL_ARRAY(char, bbuf, MAX_URL + 32);
@@ -1613,7 +1612,7 @@
return;
}
- /* TODO: handle OPTIONS request on max_forwards == 0 as well */
+ // OPTIONS with Max-Forwards:0 handled in clientProcessRequest()
if (context->http->request->method == METHOD_TRACE) {
if (context->http->request->max_forwards == 0) {
diff -u -r -N squid-3.1.7/src/client_side_request.cc squid-3.1.8/src/client_side_request.cc
--- squid-3.1.7/src/client_side_request.cc 2010-08-24 17:41:27.000000000 +1200
+++ squid-3.1.8/src/client_side_request.cc 2010-09-04 15:25:57.000000000 +1200
@@ -962,9 +962,6 @@
}
#endif
- if (request->method == METHOD_TRACE || request->method == METHOD_OPTIONS) {
- request->max_forwards = req_hdr->getInt64(HDR_MAX_FORWARDS);
- }
request->flags.cachable = http->request->cacheable();
@@ -1368,11 +1365,11 @@
assert(!virginHeadSource);
assert(!adaptedBodySource);
virginHeadSource = initiateAdaptation(
- new Adaptation::Iterator(this, request, NULL, g));
+ new Adaptation::Iterator(request, NULL, g));
// we could try to guess whether we can bypass this adaptation
// initiation failure, but it should not really happen
- assert(virginHeadSource != NULL); // Must, really
+ Must(initiated(virginHeadSource));
}
void
diff -u -r -N squid-3.1.7/src/client_side_request.h squid-3.1.8/src/client_side_request.h
--- squid-3.1.7/src/client_side_request.h 2010-08-24 17:41:25.000000000 +1200
+++ squid-3.1.8/src/client_side_request.h 2010-09-04 15:25:57.000000000 +1200
@@ -177,7 +177,7 @@
void endRequestSatisfaction();
private:
- Adaptation::Initiate *virginHeadSource;
+ CbcPointer virginHeadSource;
BodyPipe::Pointer adaptedBodySource;
bool request_satisfaction_mode;
diff -u -r -N squid-3.1.7/src/CommCalls.h squid-3.1.8/src/CommCalls.h
--- squid-3.1.7/src/CommCalls.h 2010-08-24 17:41:27.000000000 +1200
+++ squid-3.1.8/src/CommCalls.h 2010-09-04 15:25:57.000000000 +1200
@@ -141,17 +141,18 @@
// All job dialers with comm parameters are merged into one since they
// all have exactly one callback argument and differ in Params type only
template
-class CommCbMemFunT: public JobDialer, public CommDialerParamsT
+class CommCbMemFunT: public JobDialer, public CommDialerParamsT
{
public:
typedef Params_ Params;
typedef void (C::*Method)(const Params &io);
- CommCbMemFunT(C *obj, Method meth): JobDialer(obj),
- CommDialerParamsT(obj), object(obj), method(meth) {}
+ CommCbMemFunT(const CbcPointer &job, Method meth): JobDialer(job),
+ CommDialerParamsT(job.get()),
+ method(meth) {}
virtual bool canDial(AsyncCall &c) {
- return JobDialer::canDial(c) &&
+ return JobDialer::canDial(c) &&
this->params.syncWithComm();
}
@@ -162,11 +163,10 @@
}
public:
- C *object;
Method method;
protected:
- virtual void doDial() { (object->*method)(this->params); }
+ virtual void doDial() { ((&(*this->job))->*method)(this->params); }
};
diff -u -r -N squid-3.1.7/src/Common.am squid-3.1.8/src/Common.am
--- squid-3.1.7/src/Common.am 2010-08-24 17:41:27.000000000 +1200
+++ squid-3.1.8/src/Common.am 2010-09-04 15:25:57.000000000 +1200
@@ -20,6 +20,12 @@
-I$(top_builddir)/include \
$(SQUID_CPPUNIT_INC)
+## Loadable Modules requires LTDL include paths.
+## Because we need this to use the libray linking headers...
+if USE_LOADABLE_MODULES
+INCLUDES += $(INCLTDL)
+endif
+
## make all compiled sources depend on generated files
## XXX: Do we really need this? Does auto-dependency tracking work?
$(OBJS): $(top_srcdir)/include/version.h $(top_builddir)/include/autoconf.h
diff -u -r -N squid-3.1.7/src/dns_internal.cc squid-3.1.8/src/dns_internal.cc
--- squid-3.1.7/src/dns_internal.cc 2010-08-24 17:41:25.000000000 +1200
+++ squid-3.1.8/src/dns_internal.cc 2010-09-04 15:25:57.000000000 +1200
@@ -705,13 +705,15 @@
}
static void
-idnsInitVCConnected(int fd, const DnsLookupDetails &, comm_err_t status, int xerrno, void *data)
+idnsInitVCConnected(int fd, const DnsLookupDetails &details, comm_err_t status, int xerrno, void *data)
{
nsvc * vc = (nsvc *)data;
if (status != COMM_OK) {
- char buf[MAX_IPSTRLEN];
- debugs(78, 1, "idnsInitVCConnected: Failed to connect to nameserver " << nameservers[vc->ns].S.NtoA(buf,MAX_IPSTRLEN) << " using TCP!");
+ char buf[MAX_IPSTRLEN] = "";
+ if (vc->ns < nns)
+ nameservers[vc->ns].S.NtoA(buf,MAX_IPSTRLEN);
+ debugs(78, 1, HERE << "Failed to connect to nameserver " << buf << " using TCP: " << details);
comm_close(fd);
return;
}
@@ -727,7 +729,8 @@
nsvc * vc = (nsvc *)data;
delete vc->queue;
delete vc->msg;
- nameservers[vc->ns].vc = NULL;
+ if (vc->ns < nns) // XXX: idnsShutdown may have freed nameservers[]
+ nameservers[vc->ns].vc = NULL;
cbdataFree(vc);
}
@@ -737,6 +740,7 @@
char buf[MAX_IPSTRLEN];
nsvc *vc = cbdataAlloc(nsvc);
+ assert(ns < nns);
nameservers[ns].vc = vc;
vc->ns = ns;
@@ -776,6 +780,7 @@
static void
idnsSendQueryVC(idns_query * q, int ns)
{
+ assert(ns < nns);
if (nameservers[ns].vc == NULL)
idnsInitVC(ns);
@@ -828,7 +833,7 @@
} else {
if (DnsSocketB >= 0 && nameservers[ns].S.IsIPv6())
y = comm_udp_sendto(DnsSocketB, nameservers[ns].S, q->buf, q->sz);
- else
+ else if (DnsSocketA)
x = comm_udp_sendto(DnsSocketA, nameservers[ns].S, q->buf, q->sz);
}
@@ -843,16 +848,11 @@
} while ( (x<0 && y<0) && q->nsends % nns != 0);
- if (!q->need_vc) {
- if (y >= 0) {
- fd_bytes(DnsSocketB, y, FD_WRITE);
- commSetSelect(DnsSocketB, COMM_SELECT_READ, idnsRead, NULL, 0);
- }
-
- if (x >= 0) {
- fd_bytes(DnsSocketA, x, FD_WRITE);
- commSetSelect(DnsSocketA, COMM_SELECT_READ, idnsRead, NULL, 0);
- }
+ if (y > 0) {
+ fd_bytes(DnsSocketB, y, FD_WRITE);
+ }
+ if (x > 0) {
+ fd_bytes(DnsSocketA, x, FD_WRITE);
}
nameservers[ns].nqueries++;
@@ -1139,6 +1139,10 @@
debugs(78, 3, "idnsRead: starting with FD " << fd);
+ // Always keep reading. This stops (or at least makes harder) several
+ // attacks on the DNS client.
+ commSetSelect(fd, COMM_SELECT_READ, idnsRead, NULL, 0);
+
/* BUG (UNRESOLVED)
* two code lines after returning from comm_udprecvfrom()
* something overwrites the memory behind the from parameter.
@@ -1185,7 +1189,14 @@
if (ns >= 0) {
nameservers[ns].nreplies++;
- } else if (Config.onoff.ignore_unknown_nameservers) {
+ }
+
+ // Before unknown_nameservers check to avoid flooding cache.log on attacks,
+ // but after the ++ above to keep statistics right.
+ if (!lru_list.head)
+ continue; // Don't process replies if there is no pending query.
+
+ if (ns < 0 && Config.onoff.ignore_unknown_nameservers) {
static time_t last_warning = 0;
if (squid_curtime - last_warning > 60) {
@@ -1199,10 +1210,6 @@
idnsGrokReply(rbuf, len);
}
-
- if (lru_list.head) {
- commSetSelect(fd, COMM_SELECT_READ, idnsRead, NULL, 0);
- }
}
static void
@@ -1270,13 +1277,14 @@
return;
}
- vc->msg->size += len; // XXX should not access -> size directly
+ vc->msg->size += len; // XXX should not access -> size directly
if (vc->msg->contentSize() < vc->msglen) {
comm_read(fd, buf + len, vc->msglen - vc->msg->contentSize(), idnsReadVC, vc);
return;
}
+ assert(vc->ns < nns);
debugs(78, 3, "idnsReadVC: FD " << fd << ": received " <<
(int) vc->msg->contentSize() << " bytes via tcp from " <<
nameservers[vc->ns].S << ".");
@@ -1389,10 +1397,12 @@
if (DnsSocketB >= 0) {
port = comm_local_port(DnsSocketB);
debugs(78, 1, "DNS Socket created at " << addrB << ", FD " << DnsSocketB);
+ commSetSelect(DnsSocketB, COMM_SELECT_READ, idnsRead, NULL, 0);
}
if (DnsSocketA >= 0) {
port = comm_local_port(DnsSocketA);
debugs(78, 1, "DNS Socket created at " << addrA << ", FD " << DnsSocketA);
+ commSetSelect(DnsSocketA, COMM_SELECT_READ, idnsRead, NULL, 0);
}
}
@@ -1458,6 +1468,7 @@
}
}
+ // XXX: vcs are not closed/freed yet and may try to access nameservers[]
idnsFreeNameservers();
idnsFreeSearchpath();
}
diff -u -r -N squid-3.1.7/src/esi/Makefile.in squid-3.1.8/src/esi/Makefile.in
--- squid-3.1.7/src/esi/Makefile.in 2010-08-24 17:42:40.000000000 +1200
+++ squid-3.1.8/src/esi/Makefile.in 2010-09-04 15:26:28.000000000 +1200
@@ -35,11 +35,12 @@
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(top_srcdir)/src/Common.am $(top_srcdir)/src/TestHeaders.am
check_PROGRAMS =
-@HAVE_LIBEXPAT_TRUE@am__append_1 = \
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
+@HAVE_LIBEXPAT_TRUE@am__append_2 = \
@HAVE_LIBEXPAT_TRUE@ ExpatParser.cc \
@HAVE_LIBEXPAT_TRUE@ ExpatParser.h
-@HAVE_LIBXML2_TRUE@am__append_2 = \
+@HAVE_LIBXML2_TRUE@am__append_3 = \
@HAVE_LIBXML2_TRUE@ Libxml2Parser.cc \
@HAVE_LIBXML2_TRUE@ Libxml2Parser.h
@@ -295,12 +296,12 @@
CLEANFILES = testHeaders
TESTS = testHeaders
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) \
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
-I$(top_srcdir)/lib/libTrie/include \
-I$(top_builddir)/lib/libTrie/include
noinst_LTLIBRARIES = libesi.la
-ESI_PARSER_SOURCES = CustomParser.cc CustomParser.h $(am__append_1) \
- $(am__append_2)
+ESI_PARSER_SOURCES = CustomParser.cc CustomParser.h $(am__append_2) \
+ $(am__append_3)
libesi_la_SOURCES = \
Assign.cc \
Assign.h \
diff -u -r -N squid-3.1.7/src/fs/Makefile.in squid-3.1.8/src/fs/Makefile.in
--- squid-3.1.7/src/fs/Makefile.in 2010-08-24 17:42:40.000000000 +1200
+++ squid-3.1.8/src/fs/Makefile.in 2010-09-04 15:26:28.000000000 +1200
@@ -35,6 +35,7 @@
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(top_srcdir)/src/Common.am
check_PROGRAMS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
subdir = src/fs
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
@@ -293,7 +294,8 @@
CLEANFILES = testHeaders
TESTS = testHeaders
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir)
EXTRA_LTLIBRARIES = libaufs.la libdiskd.la libcoss.la libufs.la
noinst_LTLIBRARIES = $(STORE_LIBS_TO_BUILD) libfs.la
diff -u -r -N squid-3.1.7/src/fs/ufs/store_io_ufs.cc squid-3.1.8/src/fs/ufs/store_io_ufs.cc
--- squid-3.1.7/src/fs/ufs/store_io_ufs.cc 2010-08-24 17:41:26.000000000 +1200
+++ squid-3.1.8/src/fs/ufs/store_io_ufs.cc 2010-09-04 15:25:57.000000000 +1200
@@ -452,8 +452,13 @@
void *cbdata;
- if (cbdataReferenceValidDone(q->callback_data, &cbdata))
+ if (cbdataReferenceValidDone(q->callback_data, &cbdata)) {
read_(q->buf, q->size, q->offset, q->callback, cbdata);
+ } else {
+ debugs(79, 2, "UFSStoreState::kickReadQueue: this: " << this << " cbdataReferenceValidDone returned false." << " closing: " << closing << " flags.try_closing: " << flags.try_closing);
+ delete q;
+ return false;
+ }
delete q;
diff -u -r -N squid-3.1.7/src/ftp.cc squid-3.1.8/src/ftp.cc
--- squid-3.1.7/src/ftp.cc 2010-08-24 17:41:25.000000000 +1200
+++ squid-3.1.8/src/ftp.cc 2010-09-04 15:25:57.000000000 +1200
@@ -461,8 +461,8 @@
flags.rest_supported = 1;
typedef CommCbMemFunT Dialer;
- AsyncCall::Pointer closer = asyncCall(9, 5, "FtpStateData::ctrlClosed",
- Dialer(this, &FtpStateData::ctrlClosed));
+ AsyncCall::Pointer closer = JobCallback(9, 5,
+ Dialer, this, FtpStateData::ctrlClosed);
ctrl.opened(theFwdState->server_fd, closer);
if (request->method == METHOD_PUT)
@@ -1311,16 +1311,15 @@
data.read_pending = true;
typedef CommCbMemFunT TimeoutDialer;
- AsyncCall::Pointer timeoutCall = asyncCall(9, 5, "FtpStateData::ftpTimeout",
- TimeoutDialer(this,&FtpStateData::ftpTimeout));
+ AsyncCall::Pointer timeoutCall = JobCallback(9, 5,
+ TimeoutDialer, this, FtpStateData::ftpTimeout);
commSetTimeout(data.fd, Config.Timeout.read, timeoutCall);
debugs(9,5,HERE << "queueing read on FD " << data.fd);
typedef CommCbMemFunT Dialer;
entry->delayAwareRead(data.fd, data.readBuf->space(), read_sz,
- asyncCall(9, 5, "FtpStateData::dataRead",
- Dialer(this, &FtpStateData::dataRead)));
+ JobCallback(9, 5, Dialer, this, FtpStateData::dataRead));
}
void
@@ -1369,8 +1368,8 @@
if (ignoreErrno(io.xerrno)) {
typedef CommCbMemFunT TimeoutDialer;
- AsyncCall::Pointer timeoutCall = asyncCall(9, 5, "FtpStateData::ftpTimeout",
- TimeoutDialer(this,&FtpStateData::ftpTimeout));
+ AsyncCall::Pointer timeoutCall = JobCallback(9, 5,
+ TimeoutDialer, this, FtpStateData::ftpTimeout);
commSetTimeout(io.fd, Config.Timeout.read, timeoutCall);
maybeReadVirginBody();
@@ -1678,8 +1677,8 @@
}
typedef CommCbMemFunT Dialer;
- AsyncCall::Pointer call = asyncCall(9, 5, "FtpStateData::ftpWriteCommandCallback",
- Dialer(this, &FtpStateData::ftpWriteCommandCallback));
+ AsyncCall::Pointer call = JobCallback(9, 5,
+ Dialer, this, FtpStateData::ftpWriteCommandCallback);
comm_write(ctrl.fd,
ctrl.last_command,
strlen(ctrl.last_command),
@@ -1816,8 +1815,8 @@
} else {
/* XXX What about Config.Timeout.read? */
typedef CommCbMemFunT Dialer;
- AsyncCall::Pointer reader=asyncCall(9, 5, "FtpStateData::ftpReadControlReply",
- Dialer(this, &FtpStateData::ftpReadControlReply));
+ AsyncCall::Pointer reader = JobCallback(9, 5,
+ Dialer, this, FtpStateData::ftpReadControlReply);
comm_read(ctrl.fd, ctrl.buf + ctrl.offset, ctrl.size - ctrl.offset, reader);
/*
* Cancel the timeout on the Data socket (if any) and
@@ -1830,8 +1829,8 @@
}
typedef CommCbMemFunT TimeoutDialer;
- AsyncCall::Pointer timeoutCall = asyncCall(9, 5, "FtpStateData::ftpTimeout",
- TimeoutDialer(this,&FtpStateData::ftpTimeout));
+ AsyncCall::Pointer timeoutCall = JobCallback(9, 5,
+ TimeoutDialer, this, FtpStateData::ftpTimeout);
commSetTimeout(ctrl.fd, Config.Timeout.read, timeoutCall);
}
@@ -2709,8 +2708,8 @@
* dont acknowledge PASV commands.
*/
typedef CommCbMemFunT TimeoutDialer;
- AsyncCall::Pointer timeoutCall = asyncCall(9, 5, "FtpStateData::ftpTimeout",
- TimeoutDialer(ftpState,&FtpStateData::ftpTimeout));
+ AsyncCall::Pointer timeoutCall = JobCallback(9, 5,
+ TimeoutDialer, ftpState, FtpStateData::ftpTimeout);
commSetTimeout(ftpState->data.fd, 15, timeoutCall);
}
@@ -3085,8 +3084,8 @@
comm_close(io.nfd);
typedef CommCbMemFunT acceptDialer;
- AsyncCall::Pointer acceptCall = asyncCall(11, 5, "FtpStateData::ftpAcceptDataConnection",
- acceptDialer(this, &FtpStateData::ftpAcceptDataConnection));
+ AsyncCall::Pointer acceptCall = JobCallback(11, 5,
+ acceptDialer, this, FtpStateData::ftpAcceptDataConnection);
comm_accept(data.fd, acceptCall);
return;
}
@@ -3116,8 +3115,8 @@
commSetTimeout(ctrl.fd, -1, nullCall);
typedef CommCbMemFunT TimeoutDialer;
- AsyncCall::Pointer timeoutCall = asyncCall(9, 5, "FtpStateData::ftpTimeout",
- TimeoutDialer(this,&FtpStateData::ftpTimeout));
+ AsyncCall::Pointer timeoutCall = JobCallback(9, 5,
+ TimeoutDialer, this, FtpStateData::ftpTimeout);
commSetTimeout(data.fd, Config.Timeout.read, timeoutCall);
/*\todo XXX We should have a flag to track connect state...
@@ -3209,8 +3208,8 @@
commSetTimeout(ctrl.fd, -1, nullCall);
typedef CommCbMemFunT TimeoutDialer;
- AsyncCall::Pointer timeoutCall = asyncCall(9, 5, "FtpStateData::ftpTimeout",
- TimeoutDialer(this,&FtpStateData::ftpTimeout));
+ AsyncCall::Pointer timeoutCall = JobCallback(9, 5,
+ TimeoutDialer, this, FtpStateData::ftpTimeout);
commSetTimeout(data.fd, Config.Timeout.read, timeoutCall);
@@ -3221,8 +3220,8 @@
* When client code is 150 with a hostname, Accept data channel. */
debugs(9, 3, "ftpReadStor: accepting data channel");
typedef CommCbMemFunT acceptDialer;
- AsyncCall::Pointer acceptCall = asyncCall(11, 5, "FtpStateData::ftpAcceptDataConnection",
- acceptDialer(this, &FtpStateData::ftpAcceptDataConnection));
+ AsyncCall::Pointer acceptCall = JobCallback(11, 5,
+ acceptDialer, this, FtpStateData::ftpAcceptDataConnection);
comm_accept(data.fd, acceptCall);
} else {
@@ -3357,8 +3356,8 @@
} else if (code == 150) {
/* Accept data channel */
typedef CommCbMemFunT acceptDialer;
- AsyncCall::Pointer acceptCall = asyncCall(11, 5, "FtpStateData::ftpAcceptDataConnection",
- acceptDialer(ftpState, &FtpStateData::ftpAcceptDataConnection));
+ AsyncCall::Pointer acceptCall = JobCallback(11, 5,
+ acceptDialer, ftpState, FtpStateData::ftpAcceptDataConnection);
comm_accept(ftpState->data.fd, acceptCall);
/*
@@ -3369,8 +3368,8 @@
commSetTimeout(ftpState->ctrl.fd, -1, nullCall);
typedef CommCbMemFunT TimeoutDialer;
- AsyncCall::Pointer timeoutCall = asyncCall(9, 5, "FtpStateData::ftpTimeout",
- TimeoutDialer(ftpState,&FtpStateData::ftpTimeout));
+ AsyncCall::Pointer timeoutCall = JobCallback(9, 5,
+ TimeoutDialer, ftpState,FtpStateData::ftpTimeout);
commSetTimeout(ftpState->data.fd, Config.Timeout.read, timeoutCall);
return;
} else if (!ftpState->flags.tried_nlst && code > 300) {
@@ -3419,8 +3418,8 @@
} else if (code == 150) {
/* Accept data channel */
typedef CommCbMemFunT acceptDialer;
- AsyncCall::Pointer acceptCall = asyncCall(11, 5, "FtpStateData::ftpAcceptDataConnection",
- acceptDialer(ftpState, &FtpStateData::ftpAcceptDataConnection));
+ AsyncCall::Pointer acceptCall = JobCallback(11, 5,
+ acceptDialer, ftpState, FtpStateData::ftpAcceptDataConnection);
comm_accept(ftpState->data.fd, acceptCall);
/*
* Cancel the timeout on the Control socket and establish one
@@ -3430,8 +3429,8 @@
commSetTimeout(ftpState->ctrl.fd, -1, nullCall);
typedef CommCbMemFunT TimeoutDialer;
- AsyncCall::Pointer timeoutCall = asyncCall(9, 5, "FtpStateData::ftpTimeout",
- TimeoutDialer(ftpState,&FtpStateData::ftpTimeout));
+ AsyncCall::Pointer timeoutCall = JobCallback(9, 5,
+ TimeoutDialer, ftpState,FtpStateData::ftpTimeout);
commSetTimeout(ftpState->data.fd, Config.Timeout.read, timeoutCall);
} else if (code >= 300) {
if (!ftpState->flags.try_slash_hack) {
@@ -4041,8 +4040,7 @@
FtpStateData::dataCloser()
{
typedef CommCbMemFunT Dialer;
- return asyncCall(9, 5, "FtpStateData::dataClosed",
- Dialer(this, &FtpStateData::dataClosed));
+ return JobCallback(9, 5, Dialer, this, FtpStateData::dataClosed);
}
/// configures the channel with a descriptor and registers a close handler
diff -u -r -N squid-3.1.7/src/http.cc squid-3.1.8/src/http.cc
--- squid-3.1.7/src/http.cc 2010-08-24 17:41:26.000000000 +1200
+++ squid-3.1.8/src/http.cc 2010-09-04 15:25:57.000000000 +1200
@@ -139,8 +139,8 @@
* register the handler to free HTTP state data when the FD closes
*/
typedef CommCbMemFunT Dialer;
- closeHandler = asyncCall(9, 5, "httpStateData::httpStateConnClosed",
- Dialer(this,&HttpStateData::httpStateConnClosed));
+ closeHandler = JobCallback(9, 5,
+ Dialer, this, HttpStateData::httpStateConnClosed);
comm_add_close_handler(fd, closeHandler);
}
@@ -729,7 +729,7 @@
}
flags.chunked = 0;
- if (newrep->sline.protocol == PROTO_HTTP && newrep->header.hasListMember(HDR_TRANSFER_ENCODING, "chunked", ',')) {
+ if (newrep->sline.protocol == PROTO_HTTP && newrep->header.chunked()) {
flags.chunked = 1;
httpChunkDecoder = new ChunkedCodingParser;
}
@@ -1406,8 +1406,7 @@
flags.do_next_read = 0;
typedef CommCbMemFunT Dialer;
entry->delayAwareRead(fd, readBuf->space(read_size), read_size,
- asyncCall(11, 5, "HttpStateData::readReply",
- Dialer(this, &HttpStateData::readReply)));
+ JobCallback(11, 5, Dialer, this, HttpStateData::readReply));
}
}
@@ -1450,8 +1449,8 @@
* request bodies.
*/
typedef CommCbMemFunT TimeoutDialer;
- AsyncCall::Pointer timeoutCall = asyncCall(11, 5, "HttpStateData::httpTimeout",
- TimeoutDialer(this,&HttpStateData::httpTimeout));
+ AsyncCall::Pointer timeoutCall = JobCallback(11, 5,
+ TimeoutDialer, this, HttpStateData::httpTimeout);
commSetTimeout(fd, Config.Timeout.read, timeoutCall);
@@ -1769,7 +1768,7 @@
case HDR_TE: /** \par TE: */
case HDR_KEEP_ALIVE: /** \par Keep-Alive: */
case HDR_PROXY_AUTHENTICATE: /** \par Proxy-Authenticate: */
- case HDR_TRAILERS: /** \par Trailers: */
+ case HDR_TRAILER: /** \par Trailer: */
case HDR_UPGRADE: /** \par Upgrade: */
case HDR_TRANSFER_ENCODING: /** \par Transfer-Encoding: */
break;
@@ -1976,8 +1975,8 @@
}
typedef CommCbMemFunT TimeoutDialer;
- AsyncCall::Pointer timeoutCall = asyncCall(11, 5, "HttpStateData::httpTimeout",
- TimeoutDialer(this,&HttpStateData::httpTimeout));
+ AsyncCall::Pointer timeoutCall = JobCallback(11, 5,
+ TimeoutDialer, this, HttpStateData::httpTimeout);
commSetTimeout(fd, Config.Timeout.lifetime, timeoutCall);
flags.do_next_read = 1;
maybeReadVirginBody();
@@ -1986,13 +1985,13 @@
if (!startRequestBodyFlow()) // register to receive body data
return false;
typedef CommCbMemFunT Dialer;
- Dialer dialer(this, &HttpStateData::sentRequestBody);
- requestSender = asyncCall(11,5, "HttpStateData::sentRequestBody", dialer);
+ requestSender = JobCallback(11,5,
+ Dialer, this, HttpStateData::sentRequestBody);
} else {
assert(!requestBodySource);
typedef CommCbMemFunT Dialer;
- Dialer dialer(this, &HttpStateData::sendComplete);
- requestSender = asyncCall(11,5, "HttpStateData::SendComplete", dialer);
+ requestSender = JobCallback(11,5,
+ Dialer, this, HttpStateData::sendComplete);
}
if (_peer != NULL) {
@@ -2085,8 +2084,8 @@
}
typedef CommCbMemFunT Dialer;
- Dialer dialer(this, &HttpStateData::sendComplete);
- AsyncCall::Pointer call= asyncCall(11,5, "HttpStateData::SendComplete", dialer);
+ AsyncCall::Pointer call = JobCallback(11,5,
+ Dialer, this, HttpStateData::sendComplete);
comm_write(fd, "\r\n", 2, call);
}
return;
diff -u -r -N squid-3.1.7/src/HttpHeader.cc squid-3.1.8/src/HttpHeader.cc
--- squid-3.1.7/src/HttpHeader.cc 2010-08-24 17:41:26.000000000 +1200
+++ squid-3.1.8/src/HttpHeader.cc 2010-09-04 15:25:57.000000000 +1200
@@ -123,7 +123,7 @@
{"Set-Cookie", HDR_SET_COOKIE, ftStr},
{"TE", HDR_TE, ftStr},
{"Title", HDR_TITLE, ftStr},
- {"Trailers", HDR_TRAILERS, ftStr},
+ {"Trailer", HDR_TRAILER, ftStr},
{"Transfer-Encoding", HDR_TRANSFER_ENCODING, ftStr},
{"Translate", HDR_TRANSLATE, ftStr}, /* for now. may need to crop */
{"Unless-Modified-Since", HDR_UNLESS_MODIFIED_SINCE, ftStr}, /* for now ignore. may need to crop */
@@ -249,7 +249,7 @@
static HttpHeaderMask HopByHopHeadersMask;
static http_hdr_type HopByHopHeadersArr[] = {
HDR_CONNECTION, HDR_KEEP_ALIVE, /*HDR_PROXY_AUTHENTICATE,*/ HDR_PROXY_AUTHORIZATION,
- HDR_TE, HDR_TRAILERS, HDR_TRANSFER_ENCODING, HDR_UPGRADE, HDR_PROXY_CONNECTION
+ HDR_TE, HDR_TRAILER, HDR_TRANSFER_ENCODING, HDR_UPGRADE, HDR_PROXY_CONNECTION
};
/* header accounting */
@@ -647,6 +647,11 @@
addEntry(e);
}
+ if (chunked()) {
+ // RFC 2616 section 4.4: ignore Content-Length with Transfer-Encoding
+ delById(HDR_CONTENT_LENGTH);
+ }
+
PROF_stop(HttpHeaderParse);
return 1; /* even if no fields where found, it is a valid header */
reset:
diff -u -r -N squid-3.1.7/src/HttpHeader.h squid-3.1.8/src/HttpHeader.h
--- squid-3.1.7/src/HttpHeader.h 2010-08-24 17:41:26.000000000 +1200
+++ squid-3.1.8/src/HttpHeader.h 2010-09-04 15:25:57.000000000 +1200
@@ -104,7 +104,7 @@
HDR_SET_COOKIE,
HDR_TE,
HDR_TITLE,
- HDR_TRAILERS,
+ HDR_TRAILER,
HDR_TRANSFER_ENCODING,
HDR_TRANSLATE, /* IIS custom header we may need to cut off */
HDR_UNLESS_MODIFIED_SINCE, /* IIS custom header we may need to cut off */
@@ -255,6 +255,7 @@
int hasListMember(http_hdr_type id, const char *member, const char separator) const;
int hasByNameListMember(const char *name, const char *member, const char separator) const;
void removeHopByHopEntries();
+ inline bool chunked() const; ///< whether message uses chunked Transfer-Encoding
/* protected, do not use these, use interface functions instead */
Vector entries; /**< parsed fields in raw format */
@@ -282,4 +283,11 @@
SQUIDCEXTERN void httpHeaderCalcMask(HttpHeaderMask * mask, http_hdr_type http_hdr_type_enums[], size_t count);
+inline bool
+HttpHeader::chunked() const
+{
+ return has(HDR_TRANSFER_ENCODING) &&
+ hasListMember(HDR_TRANSFER_ENCODING, "chunked", ',');
+}
+
#endif /* SQUID_HTTPHEADER_H */
diff -u -r -N squid-3.1.7/src/HttpMsg.cc squid-3.1.8/src/HttpMsg.cc
--- squid-3.1.7/src/HttpMsg.cc 2010-08-24 17:41:27.000000000 +1200
+++ squid-3.1.8/src/HttpMsg.cc 2010-09-04 15:25:57.000000000 +1200
@@ -321,7 +321,7 @@
int
httpMsgIsPersistent(HttpVersion const &http_ver, const HttpHeader * hdr)
{
- if ((http_ver.major >= 1) && (http_ver.minor >= 1)) {
+ if (http_ver > HttpVersion(1, 0)) {
/*
* for modern versions of HTTP: persistent unless there is
* a "Connection: close" header.
@@ -402,6 +402,10 @@
hdr->req_start = hdr->req_end = -1;
hdr->hdr_start = hdr->hdr_end = -1;
debugs(74, 5, "httpParseInit: Request buffer is " << buf);
+ hdr->m_start = hdr->m_end = -1;
+ hdr->u_start = hdr->u_end = -1;
+ hdr->v_start = hdr->v_end = -1;
+ hdr->v_maj = hdr->v_min = 0;
}
#if MSGDODEBUG
@@ -446,190 +450,208 @@
}
#endif
-/**
- * Attempt to parse the request line.
- *
- * This will set the values in hmsg that it determines. One may end up
- * with a partially-parsed buffer; the return value tells you whether
- * the values are valid or not.
- *
- * \retval 1 if parsed correctly
- * \retval 0 if more is needed
- * \retval -1 if error
- *
- * TODO:
- * * have it indicate "error" and "not enough" as two separate conditions!
- * * audit this code as off-by-one errors are probably everywhere!
- */
int
-HttpParserParseReqLine(HttpParser *hmsg)
+HttpParser::parseRequestFirstLine()
{
- int i = 0;
- int retcode = 0;
- unsigned int maj = 0, min = 0;
- int last_whitespace = -1, line_end = -1;
+ int second_word = -1; // track the suspected URI start
+ int first_whitespace = -1, last_whitespace = -1; // track the first and last SP byte
+ int line_end = -1; // tracks the last byte BEFORE terminal \r\n or \n sequence
+
+ debugs(74, 5, HERE << "parsing possible request: " << buf);
+
+ // Single-pass parse: (provided we have the whole line anyways)
+
+ req_start = 0;
+ if (Config.onoff.relaxed_header_parser) {
+ if (Config.onoff.relaxed_header_parser < 0 && buf[req_start] == ' ')
+ debugs(74, DBG_IMPORTANT, "WARNING: Invalid HTTP Request: " <<
+ "Whitespace bytes received ahead of method. " <<
+ "Ignored due to relaxed_header_parser.");
+ // Be tolerant of prefix spaces (other bytes are valid method values)
+ for (; req_start < bufsiz && buf[req_start] == ' '; req_start++);
+ }
+ req_end = -1;
+ for (int i = 0; i < bufsiz; i++) {
+ // track first and last whitespace (SP only)
+ if (buf[i] == ' ') {
+ last_whitespace = i;
+ if (first_whitespace < req_start)
+ first_whitespace = i;
+ }
- debugs(74, 5, "httpParserParseReqLine: parsing " << hmsg->buf);
+ // track next non-SP/non-HT byte after first_whitespace
+ if (second_word < first_whitespace && buf[i] != ' ' && buf[i] != '\t') {
+ second_word = i;
+ }
- PROF_start(HttpParserParseReqLine);
- /* Find \r\n - end of URL+Version (and the request) */
- hmsg->req_end = -1;
- for (i = 0; i < hmsg->bufsiz; i++) {
- if (hmsg->buf[i] == '\n') {
- hmsg->req_end = i;
+ // locate line terminator
+ if (buf[i] == '\n') {
+ req_end = i;
+ line_end = i - 1;
break;
}
- if (i < hmsg->bufsiz - 1 && hmsg->buf[i] == '\r' && hmsg->buf[i + 1] == '\n') {
- hmsg->req_end = i + 1;
- break;
+ if (i < bufsiz - 1 && buf[i] == '\r') {
+ if (Config.onoff.relaxed_header_parser) {
+ if (Config.onoff.relaxed_header_parser < 0 && buf[i + 1] == '\r')
+ debugs(74, DBG_IMPORTANT, "WARNING: Invalid HTTP Request: " <<
+ "Series of carriage-return bytes received prior to line terminator. " <<
+ "Ignored due to relaxed_header_parser.");
+
+ // Be tolerant of invalid multiple \r prior to terminal \n
+ if (buf[i + 1] == '\n' || buf[i + 1] == '\r')
+ line_end = i - 1;
+ while (i < bufsiz - 1 && buf[i + 1] == '\r')
+ i++;
+
+ if (buf[i + 1] == '\n') {
+ req_end = i + 1;
+ break;
+ }
+ } else {
+ if (buf[i + 1] == '\n') {
+ req_end = i + 1;
+ line_end = i - 1;
+ break;
+ }
+ }
+
+ // RFC 2616 section 5.1
+ // "No CR or LF is allowed except in the final CRLF sequence"
+ return -1;
}
}
- if (hmsg->req_end == -1) {
- retcode = 0;
- goto finish;
- }
- assert(hmsg->buf[hmsg->req_end] == '\n');
- /* Start at the beginning again */
- i = 0;
-
- /* Find first non-whitespace - beginning of method */
- for (; i < hmsg->req_end && (xisspace(hmsg->buf[i])); i++);
- if (i >= hmsg->req_end) {
- retcode = 0;
- goto finish;
- }
- hmsg->m_start = i;
- hmsg->req_start = i;
-
- /* Find first whitespace - end of method */
- for (; i < hmsg->req_end && (! xisspace(hmsg->buf[i])); i++);
- if (i >= hmsg->req_end) {
- retcode = 0;
- goto finish;
- }
- hmsg->m_end = i - 1;
-
- /* Find first non-whitespace - beginning of URL+Version */
- for (; i < hmsg->req_end && (xisspace(hmsg->buf[i])); i++);
- if (i >= hmsg->req_end) {
- retcode = 0;
- goto finish;
- }
- hmsg->u_start = i;
-
- /* Find \r\n or \n - thats the end of the line. Keep track of the last whitespace! */
- for (; i <= hmsg->req_end; i++) {
- /* If \n - its end of line */
- if (hmsg->buf[i] == '\n') {
- line_end = i;
- break;
- }
- /* XXX could be off-by-one wrong! */
- if (hmsg->buf[i] == '\r' && (i + 1) <= hmsg->req_end && hmsg->buf[i+1] == '\n') {
- line_end = i;
- break;
- }
- /* If its a whitespace, note it as it'll delimit our version */
- if (hmsg->buf[i] == ' ' || hmsg->buf[i] == '\t') {
- last_whitespace = i;
- }
+ if (req_end == -1) {
+ debugs(74, 5, "Parser: retval 0: from " << req_start <<
+ "->" << req_end << ": needs more data to complete first line.");
+ return 0;
+ }
+
+ // NP: we have now seen EOL, more-data (0) cannot occur.
+ // From here on any failure is -1, success is 1
+
+
+ // Input Validation:
+
+ // Process what we now know about the line structure into field offsets
+ // generating HTTP status for any aborts as we go.
+
+ // First non-whitespace = beginning of method
+ if (req_start > line_end) {
+ return -1;
}
- if (i > hmsg->req_end) {
- retcode = 0;
- goto finish;
+ m_start = req_start;
+
+ // First whitespace = end of method
+ if (first_whitespace > line_end || first_whitespace < req_start) {
+ return -1;
+ }
+ m_end = first_whitespace - 1;
+ if (m_end < m_start) {
+ return -1;
}
- /* At this point we don't need the 'i' value; so we'll recycle it for version parsing */
+ // First non-whitespace after first SP = beginning of URL+Version
+ if (second_word > line_end || second_word < req_start) {
+ return -1;
+ }
+ u_start = second_word;
- /*
- * At this point: line_end points to the first eol char (\r or \n);
- * last_whitespace points to the last whitespace char in the URL.
- * We know we have a full buffer here!
- */
- if (last_whitespace == -1) {
- maj = 0;
- min = 9;
- hmsg->u_end = line_end - 1;
- assert(hmsg->u_end >= hmsg->u_start);
+ // RFC 1945: SP and version following URI are optional, marking version 0.9
+ // we identify this by the last whitespace being earlier than URI start
+ if (last_whitespace < second_word && last_whitespace >= req_start) {
+ v_maj = 0;
+ v_min = 9;
+ u_end = line_end;
+ return 1;
} else {
- /* Find the first non-whitespace after last_whitespace */
- /* XXX why <= vs < ? I do need to really re-audit all of this ..*/
- for (i = last_whitespace; i <= hmsg->req_end && xisspace(hmsg->buf[i]); i++);
- if (i > hmsg->req_end) {
- retcode = 0;
- goto finish;
- }
+ // otherwise last whitespace is somewhere after end of URI.
+ u_end = last_whitespace;
+ // crop any trailing whitespace in the area we think of as URI
+ for (; u_end >= u_start && xisspace(buf[u_end]); u_end--);
+ }
+ if (u_end < u_start) {
+ return -1;
+ }
- /* is it http/ ? if so, we try parsing. If not, the URL is the whole line; version is 0.9 */
- if (i + 5 >= hmsg->req_end || (strncasecmp(&hmsg->buf[i], "HTTP/", 5) != 0)) {
- maj = 0;
- min = 9;
- hmsg->u_end = line_end - 1;
- assert(hmsg->u_end >= hmsg->u_start);
- } else {
- /* Ok, lets try parsing! Yes, this needs refactoring! */
- hmsg->v_start = i;
- i += 5;
-
- /* next should be 1 or more digits */
- maj = 0;
- for (; i < hmsg->req_end && (isdigit(hmsg->buf[i])) && maj < 65536; i++) {
- maj = maj * 10;
- maj = maj + (hmsg->buf[i]) - '0';
- }
- if (maj >= 65536) {
- retcode = -1;
- goto finish;
- }
- if (i >= hmsg->req_end) {
- retcode = 0;
- goto finish;
- }
+ // Last whitespace SP = before start of protocol/version
+ if (last_whitespace >= line_end) {
+ return -1;
+ }
+ v_start = last_whitespace + 1;
+ v_end = line_end;
- /* next should be .; we -have- to have this as we have a whole line.. */
- if (hmsg->buf[i] != '.') {
- retcode = 0;
- goto finish;
- }
- if (i + 1 >= hmsg->req_end) {
- retcode = 0;
- goto finish;
- }
+ // We only accept HTTP protocol requests right now.
+ // TODO: accept other protocols; RFC 2326 (RTSP protocol) etc
+ if ((v_end - v_start +1) < 5 || strncasecmp(&buf[v_start], "HTTP/", 5) != 0) {
+#if USE_HTTP_VIOLATIONS
+ // being lax; old parser accepted strange versions
+ // there is a LOT of cases which are ambiguous, therefore we cannot use relaxed_header_parser here.
+ v_maj = 0;
+ v_min = 9;
+ u_end = line_end;
+ return 1;
+#else
+ return -1;
+#endif
+ }
- /* next should be one or more digits */
- i++;
- min = 0;
- for (; i < hmsg->req_end && (isdigit(hmsg->buf[i])) && min < 65536; i++) {
- min = min * 10;
- min = min + (hmsg->buf[i]) - '0';
- }
+ int i = v_start + sizeof("HTTP/") -1;
- if (min >= 65536) {
- retcode = -1;
- goto finish;
- }
+ /* next should be 1 or more digits */
+ if (!isdigit(buf[i])) {
+ return -1;
+ }
+ int maj = 0;
+ for (; i <= line_end && (isdigit(buf[i])) && maj < 65536; i++) {
+ maj = maj * 10;
+ maj = maj + (buf[i]) - '0';
+ }
+ // catch too-big values or missing remainders
+ if (maj >= 65536 || i > line_end) {
+ return -1;
+ }
+ v_maj = maj;
- /* Find whitespace, end of version */
- hmsg->v_end = i;
- hmsg->u_end = last_whitespace - 1;
- }
+ /* next should be .; we -have- to have this as we have a whole line.. */
+ if (buf[i] != '.') {
+ return -1;
+ }
+ // catch missing minor part
+ if (++i > line_end) {
+ return -1;
}
+ /* next should be one or more digits */
+ if (!isdigit(buf[i])) {
+ return -1;
+ }
+ int min = 0;
+ for (; i <= line_end && (isdigit(buf[i])) && min < 65536; i++) {
+ min = min * 10;
+ min = min + (buf[i]) - '0';
+ }
+ // catch too-big values or trailing garbage
+ if (min >= 65536 || i < line_end) {
+ return -1;
+ }
+ v_min = min;
+
/*
* Rightio - we have all the schtuff. Return true; we've got enough.
*/
- retcode = 1;
+ return 1;
+}
-finish:
- hmsg->v_maj = maj;
- hmsg->v_min = min;
- PROF_stop(HttpParserParseReqLine);
+int
+HttpParserParseReqLine(HttpParser *hmsg)
+{
+ PROF_start(HttpParserParseReqLine);
+ int retcode = hmsg->parseRequestFirstLine();
debugs(74, 5, "Parser: retval " << retcode << ": from " << hmsg->req_start <<
"->" << hmsg->req_end << ": method " << hmsg->m_start << "->" <<
hmsg->m_end << "; url " << hmsg->u_start << "->" << hmsg->u_end <<
- "; version " << hmsg->v_start << "->" << hmsg->v_end << " (" << maj <<
- "/" << min << ")");
-
+ "; version " << hmsg->v_start << "->" << hmsg->v_end << " (" << hmsg->v_maj <<
+ "/" << hmsg->v_min << ")");
+ PROF_stop(HttpParserParseReqLine);
return retcode;
}
-
diff -u -r -N squid-3.1.7/src/HttpMsg.h squid-3.1.8/src/HttpMsg.h
--- squid-3.1.7/src/HttpMsg.h 2010-08-24 17:41:26.000000000 +1200
+++ squid-3.1.8/src/HttpMsg.h 2010-09-04 15:25:57.000000000 +1200
@@ -123,6 +123,24 @@
class HttpParser
{
public:
+ /**
+ * Attempt to parse the first line of a new request message.
+ *
+ * Governed by:
+ * RFC 1945 section 5.1
+ * RFC 2616 section 5.1
+ *
+ * Parsing state is stored between calls. However the current implementation
+ * begins parsing from scratch on every call.
+ * The return value tells you whether the parsing state fields are valid or not.
+ *
+ * \retval -1 an error occurred. request_parse_status indicates HTTP status result.
+ * \retval 1 successful parse
+ * \retval 0 more data is needed to complete the parse
+ */
+ int parseRequestFirstLine();
+
+public:
char state;
const char *buf;
int bufsiz;
@@ -155,4 +173,42 @@
#define HTTPMSGUNLOCK(a) if(a){(a)->_unlock();(a)=NULL;}
#define HTTPMSGLOCK(a) (a)->_lock()
+// TODO: replace HTTPMSGLOCK with general RefCounting and delete this class
+/// safe HttpMsg pointer wrapper that locks and unlocks the message
+template
+class HttpMsgPointerT
+{
+public:
+ HttpMsgPointerT(): msg(NULL) {}
+ explicit HttpMsgPointerT(Msg *m): msg(m) { lock(); }
+ virtual ~HttpMsgPointerT() { unlock(); }
+
+ HttpMsgPointerT(const HttpMsgPointerT &p): msg(p.msg) { lock(); }
+ HttpMsgPointerT &operator =(const HttpMsgPointerT &p)
+ { if (msg != p.msg) { unlock(); msg = p.msg; lock(); } return *this; }
+
+ Msg &operator *() { return *msg; }
+ const Msg &operator *() const { return *msg; }
+ Msg *operator ->() { return msg; }
+ const Msg *operator ->() const { return msg; }
+ operator Msg *() { return msg; }
+ operator const Msg *() const { return msg; }
+ // add more as needed
+
+protected:
+ void lock() { if (msg) HTTPMSGLOCK(msg); } ///< prevent msg destruction
+ void unlock() { HTTPMSGUNLOCK(msg); } ///< allows/causes msg destruction
+
+private:
+ Msg *msg;
+};
+
+/// convenience wrapper to create HttpMsgPointerT<> object based on msg type
+template
+inline
+HttpMsgPointerT HttpMsgPointer(Msg *msg)
+{
+ return HttpMsgPointerT(msg);
+}
+
#endif /* SQUID_HTTPMSG_H */
diff -u -r -N squid-3.1.7/src/HttpReply.cc squid-3.1.8/src/HttpReply.cc
--- squid-3.1.7/src/HttpReply.cc 2010-08-24 17:41:26.000000000 +1200
+++ squid-3.1.8/src/HttpReply.cc 2010-09-04 15:25:57.000000000 +1200
@@ -62,7 +62,7 @@
static http_hdr_type Denied304HeadersArr[] = {
// hop-by-hop headers
HDR_CONNECTION, HDR_KEEP_ALIVE, HDR_PROXY_AUTHENTICATE, HDR_PROXY_AUTHORIZATION,
- HDR_TE, HDR_TRAILERS, HDR_TRANSFER_ENCODING, HDR_UPGRADE,
+ HDR_TE, HDR_TRAILER, HDR_TRANSFER_ENCODING, HDR_UPGRADE,
// entity headers
HDR_ALLOW, HDR_CONTENT_ENCODING, HDR_CONTENT_LANGUAGE, HDR_CONTENT_LENGTH,
HDR_CONTENT_MD5, HDR_CONTENT_RANGE, HDR_CONTENT_TYPE, HDR_LAST_MODIFIED
@@ -540,7 +540,7 @@
expectBody = true;
if (expectBody) {
- if (header.hasListMember(HDR_TRANSFER_ENCODING, "chunked", ','))
+ if (header.chunked())
theSize = -1;
else if (content_length >= 0)
theSize = content_length;
diff -u -r -N squid-3.1.7/src/HttpRequest.cc squid-3.1.8/src/HttpRequest.cc
--- squid-3.1.7/src/HttpRequest.cc 2010-08-24 17:41:25.000000000 +1200
+++ squid-3.1.8/src/HttpRequest.cc 2010-09-04 15:25:57.000000000 +1200
@@ -492,7 +492,7 @@
expectBody = Config.onoff.request_entities ? true : false;
else if (method == METHOD_PUT || method == METHOD_POST)
expectBody = true;
- else if (header.hasListMember(HDR_TRANSFER_ENCODING, "chunked", ','))
+ else if (header.chunked())
expectBody = true;
else if (content_length >= 0)
expectBody = true;
@@ -500,7 +500,7 @@
expectBody = false;
if (expectBody) {
- if (header.hasListMember(HDR_TRANSFER_ENCODING, "chunked", ','))
+ if (header.chunked())
theSize = -1;
else if (content_length >= 0)
theSize = content_length;
diff -u -r -N squid-3.1.7/src/HttpVersion.h squid-3.1.8/src/HttpVersion.h
--- squid-3.1.7/src/HttpVersion.h 2010-08-24 17:41:25.000000000 +1200
+++ squid-3.1.8/src/HttpVersion.h 2010-09-04 15:25:57.000000000 +1200
@@ -66,6 +66,23 @@
return ((this->major != that.major) || (this->minor != that.minor));
}
+ bool operator <(const HttpVersion& that) const {
+ return (this->major < that.major ||
+ (this->major == that.major && this->minor < that.minor));
+ }
+
+ bool operator >(const HttpVersion& that) const {
+ return (this->major > that.major ||
+ (this->major == that.major && this->minor > that.minor));
+ }
+
+ bool operator <=(const HttpVersion& that) const {
+ return !(*this > that);
+ }
+
+ bool operator >=(const HttpVersion& that) const {
+ return !(*this < that);
+ }
};
#endif /* SQUID_HTTPVERSION_H */
diff -u -r -N squid-3.1.7/src/icmp/Makefile.in squid-3.1.8/src/icmp/Makefile.in
--- squid-3.1.7/src/icmp/Makefile.in 2010-08-24 17:42:42.000000000 +1200
+++ squid-3.1.8/src/icmp/Makefile.in 2010-09-04 15:26:29.000000000 +1200
@@ -37,6 +37,7 @@
$(top_srcdir)/src/Common.am $(top_srcdir)/src/TestHeaders.am
check_PROGRAMS = testIcmp$(EXEEXT)
TESTS = testHeaders testIcmp$(EXEEXT)
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
EXTRA_PROGRAMS = pinger$(EXEEXT) testIcmp$(EXEEXT)
libexec_PROGRAMS = $(am__EXEEXT_1)
subdir = src/icmp
@@ -306,13 +307,8 @@
AM_CFLAGS = $(SQUID_CFLAGS)
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES = testHeaders
-INCLUDES = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/include \
- -I$(top_srcdir)/src \
- -I$(top_builddir)/include \
- $(SQUID_CPPUNIT_INC)
-
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1)
@ENABLE_PINGER_FALSE@PINGER =
# ICMP Specific Configurations
diff -u -r -N squid-3.1.7/src/ident/Makefile.in squid-3.1.8/src/ident/Makefile.in
--- squid-3.1.7/src/ident/Makefile.in 2010-08-24 17:42:42.000000000 +1200
+++ squid-3.1.8/src/ident/Makefile.in 2010-09-04 15:26:29.000000000 +1200
@@ -35,6 +35,7 @@
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(top_srcdir)/src/Common.am $(top_srcdir)/src/TestHeaders.am
check_PROGRAMS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
subdir = src/ident
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
@@ -274,13 +275,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES = testHeaders
TESTS = testHeaders
-INCLUDES = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/include \
- -I$(top_srcdir)/src \
- -I$(top_builddir)/include \
- $(SQUID_CPPUNIT_INC)
-
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1)
noinst_LTLIBRARIES = libident.la
libident_la_SOURCES = \
AclIdent.h \
diff -u -r -N squid-3.1.7/src/ip/Makefile.in squid-3.1.8/src/ip/Makefile.in
--- squid-3.1.7/src/ip/Makefile.in 2010-08-24 17:42:43.000000000 +1200
+++ squid-3.1.8/src/ip/Makefile.in 2010-09-04 15:26:29.000000000 +1200
@@ -36,6 +36,7 @@
$(top_srcdir)/src/Common.am $(top_srcdir)/src/TestHeaders.am
check_PROGRAMS = testIpAddress$(EXEEXT)
TESTS = testHeaders testIpAddress$(EXEEXT)
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
subdir = src/ip
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
@@ -287,13 +288,8 @@
AM_CFLAGS = $(SQUID_CFLAGS)
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES = testHeaders
-INCLUDES = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/include \
- -I$(top_srcdir)/src \
- -I$(top_builddir)/include \
- $(SQUID_CPPUNIT_INC)
-
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1)
noinst_LTLIBRARIES = libip.la
libip_la_SOURCES = \
IpAddress.h \
diff -u -r -N squid-3.1.7/src/Makefile.in squid-3.1.8/src/Makefile.in
--- squid-3.1.7/src/Makefile.in 2010-08-24 17:42:37.000000000 +1200
+++ squid-3.1.8/src/Makefile.in 2010-09-04 15:26:26.000000000 +1200
@@ -52,8 +52,9 @@
tests/testHttpRequest$(EXEEXT) tests/testStore$(EXEEXT) \
tests/testString$(EXEEXT) tests/testURL$(EXEEXT) \
$(STORE_TESTS)
-@USE_ADAPTATION_TRUE@am__append_1 = adaptation
-@USE_ESI_TRUE@am__append_2 = esi
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
+@USE_ADAPTATION_TRUE@am__append_2 = adaptation
+@USE_ESI_TRUE@am__append_3 = esi
EXTRA_PROGRAMS = DiskIO/DiskDaemon/diskd$(EXEEXT) unlinkd$(EXEEXT) \
dnsserver$(EXEEXT) recv-announce$(EXEEXT) \
tests/testUfs$(EXEEXT) tests/testCoss$(EXEEXT) \
@@ -62,8 +63,8 @@
sbin_PROGRAMS = squid$(EXEEXT)
bin_PROGRAMS =
libexec_PROGRAMS = $(am__EXEEXT_1) $(DISK_PROGRAMS) $(am__EXEEXT_2)
-@USE_LOADABLE_MODULES_TRUE@am__append_3 = $(LOADABLE_MODULES_SOURCES)
-@USE_LOADABLE_MODULES_TRUE@am__append_4 = \
+@USE_LOADABLE_MODULES_TRUE@am__append_4 = $(LOADABLE_MODULES_SOURCES)
+@USE_LOADABLE_MODULES_TRUE@am__append_5 = \
@USE_LOADABLE_MODULES_TRUE@ $(LIBLTDL)
subdir = src
@@ -1555,7 +1556,7 @@
test_tools.cc *.a testHeaders
TESTS = $(check_PROGRAMS) testHeaders
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) \
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
-I$(top_builddir)/src
AUTOMAKE_OPTIONS = subdir-objects
@USE_DNSSERVER_FALSE@DNSSOURCE = dns_internal.cc DnsLookupDetails.h \
@@ -1576,8 +1577,8 @@
LoadableModules.h \
LoadableModules.cc
-SUBDIRS = base acl fs repl auth ip icmp ident $(am__append_1) \
- $(am__append_2)
+SUBDIRS = base acl fs repl auth ip icmp ident $(am__append_2) \
+ $(am__append_3)
@USE_ESI_TRUE@ESI_LOCAL_LIBS = \
@USE_ESI_TRUE@ esi/libesi.la \
@USE_ESI_TRUE@ $(top_builddir)/lib/libTrie/src/libTrie.a
@@ -1793,7 +1794,7 @@
typedefs.h $(UNLINKDSOURCE) url.cc URL.h URLScheme.cc \
URLScheme.h urn.cc useragent.cc wccp.cc wccp2.cc whois.cc \
wordlist.cc wordlist.h $(WIN32_SOURCE) $(WINSVC_SOURCE) \
- $(am__append_3)
+ $(am__append_4)
noinst_HEADERS = \
client_side_request.cci \
MemBuf.cci \
@@ -1816,7 +1817,7 @@
$(REPL_OBJS) $(DISK_LIBS) $(DISK_OS_LIBS) $(CRYPTLIB) \
$(REGEXLIB) $(SNMPLIB) ${ADAPTATION_LIBS} $(ESI_LIBS) \
$(SSLLIB) -lmiscutil $(EPOLL_LIBS) $(MINGW_LIBS) $(XTRA_LIBS) \
- $(am__append_4)
+ $(am__append_5)
squid_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a \
$(DISK_LIBS) \
$(DISK_LINKOBJS) \
diff -u -r -N squid-3.1.7/src/repl/Makefile.in squid-3.1.8/src/repl/Makefile.in
--- squid-3.1.7/src/repl/Makefile.in 2010-08-24 17:42:43.000000000 +1200
+++ squid-3.1.8/src/repl/Makefile.in 2010-09-04 15:26:29.000000000 +1200
@@ -40,6 +40,7 @@
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(top_srcdir)/src/Common.am
check_PROGRAMS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
subdir = src/repl
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
@@ -288,7 +289,8 @@
CLEANFILES = testHeaders
TESTS = testHeaders
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir)
AUTOMAKE_OPTIONS = subdir-objects
# No recursion is needed for the subdirs, we build from here.
diff -u -r -N squid-3.1.7/src/Server.cc squid-3.1.8/src/Server.cc
--- squid-3.1.7/src/Server.cc 2010-08-24 17:41:26.000000000 +1200
+++ squid-3.1.8/src/Server.cc 2010-09-04 15:25:57.000000000 +1200
@@ -417,8 +417,8 @@
if (requestBodySource->getMoreData(buf)) {
debugs(9,3, HERE << "will write " << buf.contentSize() << " request body bytes");
typedef CommCbMemFunT Dialer;
- requestSender = asyncCall(93,3, "ServerStateData::sentRequestBody",
- Dialer(this, &ServerStateData::sentRequestBody));
+ requestSender = JobCallback(93,3,
+ Dialer, this, ServerStateData::sentRequestBody);
comm_write_mbuf(fd, &buf, requestSender);
} else {
debugs(9,3, HERE << "will wait for more request body bytes or eof");
@@ -544,8 +544,8 @@
}
adaptedHeadSource = initiateAdaptation(
- new Adaptation::Iterator(this, vrep, cause, group));
- startedAdaptation = adaptedHeadSource != NULL;
+ new Adaptation::Iterator(vrep, cause, group));
+ startedAdaptation = initiated(adaptedHeadSource);
Must(startedAdaptation);
}
diff -u -r -N squid-3.1.7/src/Server.h squid-3.1.8/src/Server.h
--- squid-3.1.7/src/Server.h 2010-08-24 17:41:26.000000000 +1200
+++ squid-3.1.8/src/Server.h 2010-09-04 15:25:57.000000000 +1200
@@ -186,7 +186,7 @@
#if USE_ADAPTATION
BodyPipe::Pointer virginBodyDestination; /**< to provide virgin response body */
- Adaptation::Initiate *adaptedHeadSource; /**< to get adapted response headers */
+ CbcPointer adaptedHeadSource; /**< to get adapted response headers */
BodyPipe::Pointer adaptedBodySource; /**< to consume adated response body */
bool adaptationAccessCheckPending;
diff -u -r -N squid-3.1.7/src/SquidString.h squid-3.1.8/src/SquidString.h
--- squid-3.1.7/src/SquidString.h 2010-08-24 17:41:27.000000000 +1200
+++ squid-3.1.8/src/SquidString.h 2010-09-04 15:25:57.000000000 +1200
@@ -167,6 +167,8 @@
void allocBuffer(size_type sz);
void setBuffer(char *buf, size_type sz);
+ _SQUID_INLINE_ bool nilCmp(bool, bool, int &) const;
+
/* never reference these directly! */
size_type size_; /* buffer size; 64K limit */
diff -u -r -N squid-3.1.7/src/String.cci squid-3.1.8/src/String.cci
--- squid-3.1.7/src/String.cci 2010-08-24 17:41:25.000000000 +1200
+++ squid-3.1.8/src/String.cci 2010-09-04 15:25:57.000000000 +1200
@@ -88,19 +88,31 @@
}
-int
-String::cmp (char const *aString) const
+/// compare NULL and empty strings because str*cmp() may fail on NULL strings
+/// and because we need to return consistent results for strncmp(count == 0).
+bool
+String::nilCmp(const bool thisIsNilOrEmpty, const bool otherIsNilOrEmpty, int &result) const
{
- /* strcmp fails on NULLS */
+ if (!thisIsNilOrEmpty && !otherIsNilOrEmpty)
+ return false; // result does not matter
- if (size() == 0 && (aString == NULL || aString[0] == '\0'))
- return 0;
+ if (thisIsNilOrEmpty && otherIsNilOrEmpty)
+ result = 0;
+ else if (thisIsNilOrEmpty)
+ result = -1;
+ else // otherIsNilOrEmpty
+ result = +1;
+
+ return true;
+}
- if (size() == 0)
- return -1;
- if (aString == NULL || aString[0] == '\0')
- return 1;
+int
+String::cmp (char const *aString) const
+{
+ int result = 0;
+ if (nilCmp(!size(), (!aString || !*aString), result))
+ return result;
return strcmp(termedBuf(), aString);
}
@@ -108,19 +120,9 @@
int
String::cmp (char const *aString, String::size_type count) const
{
- /* always the same at length 0 */
-
- if (count == 0)
- return 0;
-
- if (size() == 0 && (aString == NULL || aString[0] == '\0'))
- return 0;
-
- if (size() == 0)
- return -1;
-
- if (aString == NULL || aString[0] == '\0')
- return 1;
+ int result = 0;
+ if (nilCmp((!size() || !count), (!aString || !*aString || !count), result))
+ return result;
return strncmp(termedBuf(), aString, count);
}
@@ -128,16 +130,9 @@
int
String::cmp (String const &aString) const
{
- /* strcmp fails on NULLS */
-
- if (size() == 0 && aString.size() == 0)
- return 0;
-
- if (size() == 0)
- return -1;
-
- if (aString.size() == 0)
- return 1;
+ int result = 0;
+ if (nilCmp(!size(), !aString.size(), result))
+ return result;
return strcmp(termedBuf(), aString.termedBuf());
}
@@ -145,12 +140,20 @@
int
String::caseCmp(char const *aString) const
{
+ int result = 0;
+ if (nilCmp(!size(), (!aString || !*aString), result))
+ return result;
+
return strcasecmp(termedBuf(), aString);
}
int
String::caseCmp(char const *aString, String::size_type count) const
{
+ int result = 0;
+ if (nilCmp((!size() || !count), (!aString || !*aString || !count), result))
+ return result;
+
return strncasecmp(termedBuf(), aString, count);
}
diff -u -r -N squid-3.1.7/src/tests/testHttpRequest.cc squid-3.1.8/src/tests/testHttpRequest.cc
--- squid-3.1.7/src/tests/testHttpRequest.cc 2010-08-24 17:41:26.000000000 +1200
+++ squid-3.1.8/src/tests/testHttpRequest.cc 2010-09-04 15:25:57.000000000 +1200
@@ -209,3 +209,805 @@
input.reset();
error = HTTP_STATUS_NONE;
}
+
+void
+testHttpRequest::testParseRequestLine()
+{
+ MemBuf input;
+ HttpParser output;
+ input.init();
+
+ // TEST: Do we comply with RFC 1945 section 5.1 ?
+ // TEST: Do we comply with RFC 2616 section 5.1 ?
+
+ // RFC 1945 : HTTP/0.9 simple-request
+ input.append("GET /\r\n", 7);
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("GET /\r\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(2, output.m_end);
+ CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start], (output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_end);
+ CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start], (output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(9, output.v_min);
+ input.reset();
+
+ // RFC 1945 and 2616 : HTTP/1.0 full-request
+ input.append("GET / HTTP/1.0\r\n", 16);
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("GET / HTTP/1.0\r\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(2, output.m_end);
+ CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_end);
+ CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(6, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(13, output.v_end);
+ CPPUNIT_ASSERT(memcmp("HTTP/1.0", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_min);
+ input.reset();
+
+
+ // RFC 2616 : HTTP/1.1 full-request
+ input.append("GET / HTTP/1.1\r\n", 16);
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("GET / HTTP/1.1\r\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(2, output.m_end);
+ CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_end);
+ CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(6, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(13, output.v_end);
+ CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_min);
+ input.reset();
+
+ // RFC 2616 : future version full-request
+ input.append("GET / HTTP/10.12\r\n", 18);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("GET / HTTP/10.12\r\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(2, output.m_end);
+ CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_end);
+ CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(6, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(15, output.v_end);
+ CPPUNIT_ASSERT(memcmp("HTTP/10.12", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(10, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(12, output.v_min);
+ input.reset();
+
+ // space padded URL
+ input.append("GET / HTTP/1.1\r\n", 21);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("GET / HTTP/1.1\r\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(2, output.m_end);
+ CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(5, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(5, output.u_end);
+ CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(11, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(18, output.v_end);
+ CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_min);
+ input.reset();
+
+ // space padded version
+ // RFC 1945 and 2616 specify version is followed by CRLF. No intermediary bytes.
+ // NP: the terminal whitespace is a special case: invalid for even HTTP/0.9 with no version tag
+ input.append("GET / HTTP/1.1 \n", 16);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("GET / HTTP/1.1 \n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(2, output.m_end);
+ CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(13, output.u_end);
+ CPPUNIT_ASSERT(memcmp("/ HTTP/1.1", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_min);
+ input.reset();
+
+ // whitespace inside URI. (nasty but happens)
+ input.append("GET /fo o/ HTTP/1.1\n", 20);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("GET /fo o/ HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(2, output.m_end);
+ CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(9, output.u_end);
+ CPPUNIT_ASSERT(memcmp("/fo o/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(11, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(18, output.v_end);
+ CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_min);
+ input.reset();
+
+ // additional data in buffer
+ input.append("GET / HTTP/1.1\nboo!", 23);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-5, output.req_end);
+ CPPUNIT_ASSERT(memcmp("GET / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(2, output.m_end);
+ CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_end); // strangeness generated by following RFC
+ CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(10, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(17, output.v_end);
+ CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_min);
+ input.reset();
+
+ // alternative EOL sequence: NL-only
+ input.append("GET / HTTP/1.1\n", 15);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("GET / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(2, output.m_end);
+ CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_end);
+ CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(6, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(13, output.v_end);
+ CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_min);
+ input.reset();
+
+ // alternative EOL sequence: double-NL-only
+ input.append("GET / HTTP/1.1\n\n", 16);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-2, output.req_end);
+ CPPUNIT_ASSERT(memcmp("GET / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(2, output.m_end);
+ CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_end);
+ CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(6, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(13, output.v_end);
+ CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_min);
+ input.reset();
+
+ // RELAXED alternative EOL sequence: multi-CR-NL
+ input.append("GET / HTTP/1.1\r\r\r\n", 18);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ Config.onoff.relaxed_header_parser = 1;
+ // Being tolerant we can ignore and elide these apparently benign CR
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("GET / HTTP/1.1\r\r\r\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(2, output.m_end);
+ CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_end);
+ CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(6, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(13, output.v_end);
+ CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_min);
+ input.reset();
+
+ // STRICT alternative EOL sequence: multi-CR-NL
+ input.append("GET / HTTP/1.1\r\r\r\n", 18);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ // strict mode treats these as several bare-CR in the request line which is explicitly invalid.
+ Config.onoff.relaxed_header_parser = 0;
+ CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_min);
+ input.reset();
+
+ // RFC 2616 : . method
+ input.append(". / HTTP/1.1\n", 13);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp(". / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_end);
+ CPPUNIT_ASSERT(memcmp(".", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(2, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(2, output.u_end);
+ CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(4, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(11, output.v_end);
+ CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_min);
+ input.reset();
+
+ // OPTIONS with * URL
+ input.append("OPTIONS * HTTP/1.1\n", 19);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("OPTIONS * HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(6, output.m_end);
+ CPPUNIT_ASSERT(memcmp("OPTIONS", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(8, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(8, output.u_end);
+ CPPUNIT_ASSERT(memcmp("*", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(10, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(17, output.v_end);
+ CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_min);
+ input.reset();
+
+ // unknown method
+ input.append("HELLOWORLD / HTTP/1.1\n", 22);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("HELLOWORLD / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(9, output.m_end);
+ CPPUNIT_ASSERT(memcmp("HELLOWORLD", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(11, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(11, output.u_end);
+ CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(13, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(20, output.v_end);
+ CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_min);
+ input.reset();
+
+ // This stage of the parser does not yet accept non-HTTP protocol names.
+ // violations mode treats them as HTTP/0.9 requests!
+ input.append("GET / FOO/1.0\n", 14);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+#if USE_HTTP_VIOLATIONS
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(12, output.u_end);
+ CPPUNIT_ASSERT(memcmp("/ FOO/1.0", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(9, output.v_min);
+#else
+ CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(4, output.u_end);
+ CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_min);
+#endif
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("GET / FOO/1.0\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(2, output.m_end);
+ CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(6, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(12, output.v_end);
+ CPPUNIT_ASSERT(memcmp("FOO/1.0", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
+ input.reset();
+
+ // RELAXED space padded method (in strict mode SP is reserved so invalid as a method byte)
+ input.append(" GET / HTTP/1.1\n", 16);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ Config.onoff.relaxed_header_parser = 1;
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(1, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("GET / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(1, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(3, output.m_end);
+ CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(5, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(5, output.u_end);
+ CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(7, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(14, output.v_end);
+ CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_min);
+ input.reset();
+
+ // STRICT space padded method (in strict mode SP is reserved so invalid as a method byte)
+ input.append(" GET / HTTP/1.1\n", 16);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ Config.onoff.relaxed_header_parser = 0;
+ CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp(" GET / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_min);
+ input.reset();
+
+ // tab padded method (NP: tab is not SP so treated as any other binary)
+ input.append("\tGET / HTTP/1.1\n", 16);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("\tGET / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(3, output.m_end);
+ CPPUNIT_ASSERT(memcmp("\tGET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(5, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(5, output.u_end);
+ CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(7, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(14, output.v_end);
+ CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_min);
+ input.reset();
+
+ input.append("GET", 3);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(0, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_min);
+ input.reset();
+
+ input.append("GET ", 4);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(0, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_min);
+ input.reset();
+
+ input.append("GET / HT", 8);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(0, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_min);
+ input.reset();
+
+ input.append("GET / HTTP/1.1", 14);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(0, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_min);
+ input.reset();
+
+ // method-only
+ input.append("A\n", 2);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("A\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_min);
+ input.reset();
+
+ // no method (but in a form which is ambiguous with HTTP/0.9 simple-request)
+ input.append("/ HTTP/1.0\n", 11);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("/ HTTP/1.0\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_end);
+ CPPUNIT_ASSERT(memcmp("/", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(2, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(9, output.u_end);
+ CPPUNIT_ASSERT(memcmp("HTTP/1.0", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(9, output.v_min);
+ input.reset();
+
+ // RELAXED no method (an invalid format)
+ input.append(" / HTTP/1.0\n", 12);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ // When tolerantly ignoring SP prefix this case becomes ambiguous with HTTP/0.9 simple-request)
+ Config.onoff.relaxed_header_parser = 1;
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(1, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("/ HTTP/1.0\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(1, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(1, output.m_end);
+ CPPUNIT_ASSERT(memcmp("/", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(3, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(10, output.u_end);
+ CPPUNIT_ASSERT(memcmp("HTTP/1.0", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(9, output.v_min);
+ input.reset();
+
+ // STRICT no method (an invalid format)
+ input.append(" / HTTP/1.0\n", 12);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ // When tolerantly ignoring SP prefix this case becomes ambiguous with HTTP/0.9 simple-request)
+ Config.onoff.relaxed_header_parser = 0;
+ CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp(" / HTTP/1.0\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_min);
+ input.reset();
+
+ // binary code in method (strange but ...)
+ input.append("GET\x0B / HTTP/1.1\n", 16);
+ //printf("TEST: %d-%d/%d '%.*s'\n", output.req_start, output.req_end, input.contentSize(), 16, input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("GET\x0B / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(3, output.m_end);
+ CPPUNIT_ASSERT(memcmp("GET\x0B", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(5, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(5, output.u_end);
+ CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(7, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(14, output.v_end);
+ CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_min);
+ input.reset();
+
+ // CR in method
+ // RFC 2616 sec 5.1 prohibits CR other than in terminator.
+ input.append("GET\r / HTTP/1.1\r\n", 16);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_min);
+ input.reset();
+
+ // binary code NUL! in method (strange but ...)
+ input.append("GET\0 / HTTP/1.1\n", 16);
+ //printf("TEST: %d-%d/%d '%.*s'\n", output.req_start, output.req_end, input.contentSize(), 16, input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("GET\0 / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(3, output.m_end);
+ CPPUNIT_ASSERT(memcmp("GET\0", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(5, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(5, output.u_end);
+ CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(7, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(14, output.v_end);
+ CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_min);
+ input.reset();
+
+ // no URL (grammer otherwise correct)
+ input.append("GET HTTP/1.1\n", 14);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("GET HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(2, output.m_end);
+ CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(5, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(12, output.u_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
+ CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(9, output.v_min);
+ input.reset();
+
+ // no URL (grammer invalid, ambiguous with RFC 1945 HTTP/0.9 simple-request)
+ input.append("GET HTTP/1.1\n", 13);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("GET HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(2, output.m_end);
+ CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(11, output.u_end);
+ CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(9, output.v_min);
+ input.reset();
+
+ // no version
+ input.append("GET / HTTP/\n", 12);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("GET / HTTP/\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(2, output.m_end);
+ CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_end);
+ CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(6, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(10, output.v_end);
+ CPPUNIT_ASSERT(memcmp("HTTP/", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_min);
+ input.reset();
+
+ // no major version
+ input.append("GET / HTTP/.1\n", 14);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("GET / HTTP/.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(2, output.m_end);
+ CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_end);
+ CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(6, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(12, output.v_end);
+ CPPUNIT_ASSERT(memcmp("HTTP/.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_min);
+ input.reset();
+
+ // no version dot
+ input.append("GET / HTTP/11\n", 14);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("GET / HTTP/11\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(2, output.m_end);
+ CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_end);
+ CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(6, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(12, output.v_end);
+ CPPUNIT_ASSERT(memcmp("HTTP/11", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_min);
+ input.reset();
+
+ // no minor version
+ input.append("GET / HTTP/1.\n", 14);
+ //printf("TEST: '%s'\n",input.content());
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("GET / HTTP/1.\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(2, output.m_end);
+ CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(4, output.u_end);
+ CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(6, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(12, output.v_end);
+ CPPUNIT_ASSERT(memcmp("HTTP/1.", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_min);
+ input.reset();
+
+ // binary line
+ input.append("\xB\xC\xE\xF\n", 5);
+ //printf("TEST: binary-line\n");
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("\xB\xC\xE\xF\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_min);
+ input.reset();
+
+ // mixed whitespace line
+ // We accept non-space binary bytes for method so first \t shows up as that
+ // but remaining space and tabs are skipped searching for URI-start
+ input.append("\t \t \t\n", 6);
+ //printf("TEST: mixed whitespace\n");
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
+ CPPUNIT_ASSERT(memcmp("\t \t \t\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(0, output.m_end);
+ CPPUNIT_ASSERT(memcmp("\t", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
+ CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_min);
+ input.reset();
+
+ // mixed whitespace line with CR middle
+ // CR aborts on sight, so even initial \t method is not marked as above
+ // (not when parsing clean with whole line available anyway)
+ input.append("\t \r \n", 6);
+ //printf("TEST: mixed whitespace with CR\n");
+ HttpParserInit(&output, input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(0, output.req_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.m_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
+ CPPUNIT_ASSERT_EQUAL(0, output.v_min);
+ input.reset();
+}
diff -u -r -N squid-3.1.7/src/tests/testHttpRequest.h squid-3.1.8/src/tests/testHttpRequest.h
--- squid-3.1.7/src/tests/testHttpRequest.h 2010-08-24 17:41:25.000000000 +1200
+++ squid-3.1.8/src/tests/testHttpRequest.h 2010-09-04 15:25:57.000000000 +1200
@@ -15,6 +15,7 @@
CPPUNIT_TEST( testCreateFromUrl );
CPPUNIT_TEST( testIPv6HostColonBug );
CPPUNIT_TEST( testSanityCheckStartLine );
+ CPPUNIT_TEST( testParseRequestLine );
CPPUNIT_TEST_SUITE_END();
public:
@@ -25,6 +26,7 @@
void testCreateFromUrl();
void testIPv6HostColonBug();
void testSanityCheckStartLine();
+ void testParseRequestLine();
};
#endif
diff -u -r -N squid-3.1.7/src/url.cc squid-3.1.8/src/url.cc
--- squid-3.1.7/src/url.cc 2010-08-24 17:41:27.000000000 +1200
+++ squid-3.1.8/src/url.cc 2010-09-04 15:25:57.000000000 +1200
@@ -38,6 +38,13 @@
#include "URLScheme.h"
#include "rfc1738.h"
+static HttpRequest *urlParseFinish(const HttpRequestMethod& method,
+ const protocol_t protocol,
+ const char *const urlpath,
+ const char *const host,
+ const char *const login,
+ const int port,
+ HttpRequest *request);
static HttpRequest *urnParse(const HttpRequestMethod& method, char *urn);
static const char valid_hostname_chars_u[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -222,6 +229,11 @@
if (sscanf(url, "%[^:]:%d", host, &port) < 1)
return NULL;
+ } else if ((method == METHOD_OPTIONS || method == METHOD_TRACE) &&
+ strcmp(url, "*") == 0) {
+ protocol = PROTO_HTTP;
+ port = urlDefaultPort(protocol);
+ return urlParseFinish(method, protocol, url, host, login, port, request);
} else if (!strncmp(url, "urn:", 4)) {
return urnParse(method, url);
} else {
@@ -402,6 +414,23 @@
}
}
+ return urlParseFinish(method, protocol, urlpath, host, login, port, request);
+}
+
+/**
+ * Update request with parsed URI data. If the request arg is
+ * non-NULL, put parsed values there instead of allocating a new
+ * HttpRequest.
+ */
+static HttpRequest *
+urlParseFinish(const HttpRequestMethod& method,
+ const protocol_t protocol,
+ const char *const urlpath,
+ const char *const host,
+ const char *const login,
+ const int port,
+ HttpRequest *request)
+{
if (NULL == request)
request = new HttpRequest(method, protocol, urlpath);
else {
@@ -767,8 +796,10 @@
if (r->method == METHOD_CONNECT)
return 1;
- if (r->method == METHOD_TRACE)
- return 1;
+ // we support OPTIONS and TRACE directed at us (with a 501 reply, for now)
+ // we also support forwarding OPTIONS and TRACE, except for the *-URI ones
+ if (r->method == METHOD_OPTIONS || r->method == METHOD_TRACE)
+ return (r->max_forwards == 0 || r->urlpath != "*");
if (r->method == METHOD_PURGE)
return 1;
diff -u -r -N squid-3.1.7/test-suite/Makefile.in squid-3.1.8/test-suite/Makefile.in
--- squid-3.1.7/test-suite/Makefile.in 2010-08-24 17:42:44.000000000 +1200
+++ squid-3.1.8/test-suite/Makefile.in 2010-09-04 15:26:29.000000000 +1200
@@ -47,6 +47,7 @@
VirtualDeleteOperator$(EXEEXT) StackTest$(EXEEXT) \
refcount$(EXEEXT) splay$(EXEEXT) MemPoolTest$(EXEEXT) \
mem_node_test$(EXEEXT) mem_hdr_test$(EXEEXT) $(am__EXEEXT_2)
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
EXTRA_PROGRAMS = mem_node_test$(EXEEXT) membanger$(EXEEXT) \
splay$(EXEEXT) tcp-banger2$(EXEEXT)
subdir = test-suite
@@ -355,7 +356,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES =
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir)
AUTOMAKE_OPTIONS = subdir-objects
LDADD = \
$(top_builddir)/compat/libcompat.la \
diff -u -r -N squid-3.1.7/tools/Makefile.in squid-3.1.8/tools/Makefile.in
--- squid-3.1.7/tools/Makefile.in 2010-08-24 17:42:45.000000000 +1200
+++ squid-3.1.8/tools/Makefile.in 2010-09-04 15:26:30.000000000 +1200
@@ -42,6 +42,7 @@
$(top_srcdir)/src/Common.am
check_PROGRAMS =
TESTS =
+@USE_LOADABLE_MODULES_TRUE@am__append_1 = $(INCLTDL)
bin_PROGRAMS = squidclient$(EXEEXT)
libexec_PROGRAMS = cachemgr$(CGIEXT)$(EXEEXT)
subdir = tools
@@ -310,7 +311,8 @@
AM_CXXFLAGS = $(SQUID_CXXFLAGS)
CLEANFILES = stub_debug.cc time.cc
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/src \
- -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) -I$(srcdir)
+ -I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(am__append_1) \
+ -I$(srcdir)
AUTOMAKE_OPTIONS = subdir-objects
# Neither of these should be disted from here.