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>/\"libltdl\/lt_system.h\"/g' $src/$f |
-                sed 's/<libltdl\/lt__glibc.h>/\"libltdl\/lt__glibc.h\"/g' |
-                sed 's/<libltdl\/lt_error.h>/\"libltdl\/lt_error.h\"/g' |
-                sed 's/<libltdl\/lt_dlloader.h>/\"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 <http://www.squid-cache.org/bugs/>.
 #
@@ -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 <stdio.h>
+#include <stdlib.h>
+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 <libltdl/lt_system.h>
 
 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 <libltdl/lt_system.h>
 
 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 <libltdl/lt__glibc.h>
+#  include <libltdl/lt_system.h>
 #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 <libltdl/lt_system.h>
+#include <libltdl/lt_error.h>
+#include <libltdl/lt_dlloader.h>
 
 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 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
 <HTML>
 <HEAD>
- <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.66">
- <TITLE>Squid 3.1.7 release notes</TITLE>
+ <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.65">
+ <TITLE>Squid 3.1.8 release notes</TITLE>
 </HEAD>
 <BODY>
-<H1>Squid 3.1.7 release notes</H1>
+<H1>Squid 3.1.8 release notes</H1>
 
 <H2>Squid Developers</H2>
 <HR>
@@ -70,7 +70,7 @@
 <HR>
 <H2><A NAME="s1">1.</A> <A HREF="#toc1">Notice</A></H2>
 
-<P>The Squid Team are pleased to announce the release of Squid-3.1.7</P>
+<P>The Squid Team are pleased to announce the release of Squid-3.1.8</P>
 <P>This new release is available for download from 
 <A HREF="http://www.squid-cache.org/Versions/v3/3.1/">http://www.squid-cache.org/Versions/v3/3.1/</A> or the 
 <A HREF="http://www.squid-cache.org/Mirrors/http-mirrors.html">mirrors</A>.</P>
@@ -89,7 +89,6 @@
 <P>
 <UL>
 <LI>The lack of some features available in Squid-2.x series. See the regression sections below for full details.</LI>
-<LI>IPv6 split-stack support for Windows XP, MacOS X, OpenBSD and maybe others is not complete.</LI>
 <LI>CVE-2009-0801 : NAT interception vulnerability to malicious clients.</LI>
 </UL>
 </P>
@@ -97,7 +96,6 @@
 <P>Currently known issues which only depends on available developer time and may still be resolved in a future 3.1 release are:</P>
 <P>
 <UL>
-<LI>An ongoing slow FD leak introduced somewhere during the Squid-3.0 cycle.</LI>
 <LI>Windows support is still largely missing.</LI>
 <LI>AIX support for building with the IBM compiler is broken.</LI>
 </UL>
@@ -1337,8 +1335,8 @@
 <DT><B>https_port intercept ssl-bump connection-auth[=on|off]</B><DD>
 <P>New port options. see http_port.</P>
 
-<DT><B>icap_service bypass=on|off|1|0 routing=on|off|1|0</B><DD>
-<P>New options 'bypass=' and 'routing='.
+<DT><B>icap_service bypass=on|off|1|0 routing=on|off|1|0 ipv6=on|off</B><DD>
+<P>New options 'bypass=', 'routing=' and 'ipv6='.
 <PRE>
         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.
         
 </PRE>
 </P>
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<MessageRep*>(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<libecap::adapter::Xaction> 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<Initiate> 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<Adaptation::Icap::Launcher, Adaptation::Icap::XactAbortInfo>
-{
-public:
-    typedef void (Adaptation::Icap::Launcher::*DialMethod)(Adaptation::Icap::XactAbortInfo &);
-    XactAbortCall(Adaptation::Icap::Launcher *launcer, DialMethod aMethod,
-                  const Adaptation::Icap::XactAbortInfo &info):
-            UnaryMemFunT<Adaptation::Icap::Launcher, Adaptation::Icap::XactAbortInfo>(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<ModXact> 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<Adaptation::Icap::ServiceRep*>(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<Adaptation::Icap::ServiceRep*>(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<Adaptation::Initiate> 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<Adaptation::Icap::Xaction, CommConnectCbParams> Dialer;
-        Dialer dialer(this, &Adaptation::Icap::Xaction::noteCommConnected);
+        CbcPointer<Xaction> 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<Adaptation::Icap::Xaction, CommTimeoutCbParams> 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<Adaptation::Icap::Xaction, CommCloseCbParams> 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<Adaptation::Icap::Xaction, CommConnectCbParams> 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<Adaptation::Icap::Xaction, CommIoCbParams> 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<Adaptation::Icap::Xaction, CommTimeoutCbParams> 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<Adaptation::Icap::Xaction, CommIoCbParams> 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<Adaptation::Icap::Launcher*>(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<Launcher*>(theInitiator.get());
+        // launcher may be nil if initiator is invalid
+        CallJobHere1(91,5, CbcPointer<Launcher>(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<Initiator, HttpMsg*> 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<Initiator> &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<Initiator> &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<Initiator> 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::Initiate>
+Adaptation::Initiator::initiateAdaptation(Initiate *x)
 {
-    if ((x = dynamic_cast<Initiate*>(Initiate::AsyncStart(x))))
-        x = cbdataReference(x);
-    return x;
+    CbcPointer<Initiate> i(x);
+    x->initiator(this);
+    Start(x);
+    return i;
 }
 
 void
-Adaptation::Initiator::clearAdaptation(Initiate *&x)
+Adaptation::Initiator::clearAdaptation(CbcPointer<Initiate> &x)
 {
-    assert(x);
-    cbdataReferenceDone(x);
+    x.clear();
 }
 
 void
-Adaptation::Initiator::announceInitiatorAbort(Initiate *&x)
+Adaptation::Initiator::announceInitiatorAbort(CbcPointer<Initiate> &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<Initiate> 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<Initiate> &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<Initiate> &x);
+
+    /// Must(initiated(initiate)) instead of Must(initiate.set()), for clarity
+    bool initiated(const CbcPointer<AsyncJob> &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<Adaptation::Initiate> 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 Job>
+class JobDialer: public CallDialer
+{
+public:
+    typedef Job DestClass;
+    typedef CbcPointer<Job> 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 <class Dialer>
+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<Class>((job), &Class::method))
+
+#define CallJobHere1(debugSection, debugLevel, job, Class, method, arg1) \
+    CallJob((debugSection), (debugLevel), __FILE__, __LINE__, \
+        (#Class "::" #method), \
+        JobMemFun<Class>((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<Dialer::DestClass>(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 C>
-class NullaryMemFunT: public JobDialer
+template <class Job>
+class NullaryMemFunT: public JobDialer<Job>
 {
 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<Job> &aJob, Method aMethod):
+            JobDialer<Job>(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 C, class Argument1>
-class UnaryMemFunT: public JobDialer
+template <class Job, class Argument1>
+class UnaryMemFunT: public JobDialer<Job>
 {
 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<Job> &aJob, Method aMethod,
+                          const Argument1 &anArg1): JobDialer<Job>(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 <class C>
 NullaryMemFunT<C>
-MemFun(C *object, typename NullaryMemFunT<C>::Method method)
+JobMemFun(const CbcPointer<C> &job, typename NullaryMemFunT<C>::Method method)
 {
-    return NullaryMemFunT<C>(object, method);
+    return NullaryMemFunT<C>(job, method);
 }
 
 template <class C, class Argument1>
 UnaryMemFunT<C, Argument1>
-MemFun(C *object, typename UnaryMemFunT<C, Argument1>::Method method,
-       Argument1 arg1)
+JobMemFun(const CbcPointer<C> &job, typename UnaryMemFunT<C, Argument1>::Method method,
+          Argument1 arg1)
+{
+    return UnaryMemFunT<C, Argument1>(job, method, arg1);
+}
+
+
+// inlined methods
+
+template<class Job>
+JobDialer<Job>::JobDialer(const JobPointer &aJob): job(aJob)
+{
+}
+
+template<class Job>
+JobDialer<Job>::JobDialer(const JobDialer<Job> &d): CallDialer(d), job(d.job)
 {
-    return UnaryMemFunT<C, Argument1>(object, method, arg1);
+}
+
+template<class Job>
+bool
+JobDialer<Job>::canDial(AsyncCall &call)
+{
+    if (!job)
+        return call.cancel("job gone");
+
+    return job->canBeCalled(call);
+}
+
+template<class Job>
+void
+JobDialer<Job>::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<AsyncJob> 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 Cbc>
+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<AsyncJob> 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 <class Dialer>
-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 Cbc>
+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<Cbc> &o) const { return lock == o.lock; }
+
+    CbcPointer &operator =(const CbcPointer &p);
+
+    /// support converting a child cbc pointer into a parent cbc pointer
+    template <typename Other>
+    CbcPointer(const CbcPointer<Other> &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 <typename Other>
+    CbcPointer &operator =(const CbcPointer<Other> &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 <class Cbc>
+inline
+std::ostream &operator <<(std::ostream &os, const CbcPointer<Cbc> &p)
+{
+    return p.print(os);
+}
+
+// inlined methods
+
+template<class Cbc>
+CbcPointer<Cbc>::CbcPointer(): cbc(NULL), lock(NULL)
+{
+}
+
+template<class Cbc>
+CbcPointer<Cbc>::CbcPointer(Cbc *aCbc): cbc(aCbc), lock(NULL)
+{
+    if (cbc)
+        lock = cbdataReference(cbc->toCbdata());
+}
+
+template<class Cbc>
+CbcPointer<Cbc>::CbcPointer(const CbcPointer &d): cbc(d.cbc), lock(NULL)
+{
+    if (d.lock && cbdataReferenceValid(d.lock))
+        lock = cbdataReference(d.lock);
+}
+
+template<class Cbc>
+CbcPointer<Cbc>::~CbcPointer()
+{
+    clear();
+}
+
+template<class Cbc>
+CbcPointer<Cbc> &CbcPointer<Cbc>::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<class Cbc>
+void
+CbcPointer<Cbc>::clear()
+{
+    cbdataReferenceDone(lock); // lock may be nil before and will be nil after
+    cbc = NULL;
+}
+
+template<class Cbc>
+Cbc *
+CbcPointer<Cbc>::raw() const
+{
+    return cbc;
+}
+
+template<class Cbc>
+Cbc *
+CbcPointer<Cbc>::get() const
+{
+    return (lock && cbdataReferenceValid(lock)) ? cbc : NULL;
+}
+
+template<class Cbc>
+Cbc &
+CbcPointer<Cbc>::operator *() const
+{
+    Cbc *c = get();
+    Must(c);
+    return *c;
+}
+
+template<class Cbc>
+Cbc *
+CbcPointer<Cbc>::operator ->() const
+{
+    Cbc *c = get();
+    Must(c);
+    return c;
+}
+
+template <class Cbc>
+std::ostream &CbcPointer<Cbc>::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<BodyProducer, BodyPipe::Pointer> 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<BodyConsumer, BodyPipe::Pointer> 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<BodyProducer> Pointer;
+
     BodyProducer():AsyncJob("BodyProducer") {}
     virtual ~BodyProducer() {}
 
@@ -31,6 +33,8 @@
 class BodyConsumer: virtual public AsyncJob
 {
 public:
+    typedef CbcPointer<BodyConsumer> 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<ConnStateData, CommIoCbParams> 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<ConnStateData, CommTimeoutCbParams> 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<clientReplyContext *>(node->data.getRaw());
         assert (repContext);
@@ -2928,8 +2932,8 @@
          * if we don't close() here, we still need a timeout handler!
          */
         typedef CommCbMemFunT<ConnStateData, CommTimeoutCbParams> 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<ConnStateData, CommCloseCbParams> 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<ConnStateData, CommTimeoutCbParams> 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<ConnStateData, CommCloseCbParams> 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<ConnStateData, CommTimeoutCbParams> 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<ConnStateData, CommCloseCbParams> 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<Adaptation::Initiate> 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 C, class Params_>
-class CommCbMemFunT: public JobDialer, public CommDialerParamsT<Params_>
+class CommCbMemFunT: public JobDialer<C>, public CommDialerParamsT<Params_>
 {
 public:
     typedef Params_ Params;
     typedef void (C::*Method)(const Params &io);
 
-    CommCbMemFunT(C *obj, Method meth): JobDialer(obj),
-            CommDialerParamsT<Params>(obj), object(obj), method(meth) {}
+    CommCbMemFunT(const CbcPointer<C> &job, Method meth): JobDialer<C>(job),
+            CommDialerParamsT<Params_>(job.get()),
+            method(meth) {}
 
     virtual bool canDial(AsyncCall &c) {
-        return JobDialer::canDial(c) &&
+        return JobDialer<C>::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<FtpStateData, CommCloseCbParams> 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<FtpStateData, CommTimeoutCbParams> 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<FtpStateData, CommIoCbParams> 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<FtpStateData, CommTimeoutCbParams> 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<FtpStateData, CommIoCbParams> 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<FtpStateData, CommIoCbParams> 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<FtpStateData, CommTimeoutCbParams> 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<FtpStateData, CommTimeoutCbParams> 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<FtpStateData, CommAcceptCbParams> 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<FtpStateData, CommTimeoutCbParams> 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<FtpStateData, CommTimeoutCbParams> 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<FtpStateData, CommAcceptCbParams> 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<FtpStateData, CommAcceptCbParams> 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<FtpStateData, CommTimeoutCbParams> 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<FtpStateData, CommAcceptCbParams> 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<FtpStateData, CommTimeoutCbParams> 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<FtpStateData, CommCloseCbParams> 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<HttpStateData, CommCloseCbParams> 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<HttpStateData, CommIoCbParams> 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<HttpStateData, CommTimeoutCbParams> 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<HttpStateData, CommTimeoutCbParams> 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<HttpStateData, CommIoCbParams> 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<HttpStateData, CommIoCbParams> 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<HttpStateData, CommIoCbParams> 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<HttpHeaderEntry *> 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 Msg>
+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 <class Msg>
+inline
+HttpMsgPointerT<Msg> HttpMsgPointer(Msg *msg)
+{
+    return HttpMsgPointerT<Msg>(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<ServerStateData, CommIoCbParams> 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<Adaptation::Initiate> 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.
