diff -u -r -N squid-3.5.21/ChangeLog squid-3.5.22/ChangeLog
--- squid-3.5.21/ChangeLog 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/ChangeLog 2016-10-10 08:58:01.000000000 +1300
@@ -1,3 +1,17 @@
+Changes to squid-3.5.22 (09 Oct 2016):
+
+ - Bug 4594: build failure with clang 3.9
+ - Bug 4471: revalidation does not work when expired cached object lacks Last-Modified
+ - Bug 4302 pt2: IPv6 support for IPFilter v5 transparent interception
+ - Bug 4228: ./configure bug/typo in r14394
+ - Bug 3819: "fd >= 0" assertion in file_write() during reconfiguration
+ - Bug 2833: Collapse internal revalidation requests (SMP-unaware caches)
+ - Fix logged request size (%http::>st) and other size-related %codes
+ - Fix some memory leaks from putenv()
+ - Fix memory leaks from url_rewrite_extras and store_id_extras on reconfigure/shutdown
+ - Fix segfault crash when debugging section 4 at level 9
+ - HTTP: MUST ignore a [revalidation] response with an older Date header
+
Changes to squid-3.5.21 (08 Sep 2016):
- Bug 4563: duplicate code in httpMakeVaryMark
diff -u -r -N squid-3.5.21/configure squid-3.5.22/configure
--- squid-3.5.21/configure 2016-09-09 07:00:42.000000000 +1200
+++ squid-3.5.22/configure 2016-10-10 09:04:24.000000000 +1300
@@ -1,7 +1,7 @@
#! /bin/sh
# From configure.ac Revision.
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for Squid Web Proxy 3.5.21.
+# Generated by GNU Autoconf 2.69 for Squid Web Proxy 3.5.22.
#
# Report bugs to .
#
@@ -595,8 +595,8 @@
# Identity of this package.
PACKAGE_NAME='Squid Web Proxy'
PACKAGE_TARNAME='squid'
-PACKAGE_VERSION='3.5.21'
-PACKAGE_STRING='Squid Web Proxy 3.5.21'
+PACKAGE_VERSION='3.5.22'
+PACKAGE_STRING='Squid Web Proxy 3.5.22'
PACKAGE_BUGREPORT='http://bugs.squid-cache.org/'
PACKAGE_URL=''
@@ -1636,7 +1636,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.5.21 to adapt to many kinds of systems.
+\`configure' configures Squid Web Proxy 3.5.22 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1707,7 +1707,7 @@
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of Squid Web Proxy 3.5.21:";;
+ short | recursive ) echo "Configuration of Squid Web Proxy 3.5.22:";;
esac
cat <<\_ACEOF
@@ -2119,7 +2119,7 @@
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-Squid Web Proxy configure 3.5.21
+Squid Web Proxy configure 3.5.22
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -3223,7 +3223,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.5.21, which was
+It was created by Squid Web Proxy $as_me 3.5.22, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -4090,7 +4090,7 @@
# Define the identity of the package.
PACKAGE='squid'
- VERSION='3.5.21'
+ VERSION='3.5.22'
cat >>confdefs.h <<_ACEOF
@@ -30339,7 +30339,7 @@
fi
if test "x$KRB5LIBS" = "x"; then
- if test test "x$with_heimdal_krb5" = "xyes"; then
+ if test "x$with_heimdal_krb5" = "xyes"; then
as_fn_error $? "Required Heimdal Kerberos library not found" "$LINENO" 5
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Heimdal Kerberos library not found" >&5
@@ -30857,7 +30857,7 @@
fi
if test "x$KRB5LIBS" = "x"; then
- if test test "x$with_gnugss" = "xyes"; then
+ if test "x$with_gnugss" = "xyes"; then
as_fn_error $? "Required GNU GSS Kerberos library not found" "$LINENO" 5
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: GNU GSS Kerberos library not found" >&5
@@ -41876,7 +41876,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.5.21, which was
+This file was extended by Squid Web Proxy $as_me 3.5.22, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -41942,7 +41942,7 @@
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-Squid Web Proxy config.status 3.5.21
+Squid Web Proxy config.status 3.5.22
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff -u -r -N squid-3.5.21/configure.ac squid-3.5.22/configure.ac
--- squid-3.5.21/configure.ac 2016-09-09 07:00:41.000000000 +1200
+++ squid-3.5.22/configure.ac 2016-10-10 09:04:22.000000000 +1300
@@ -5,7 +5,7 @@
## Please see the COPYING and CONTRIBUTORS files for details.
##
-AC_INIT([Squid Web Proxy],[3.5.21],[http://bugs.squid-cache.org/],[squid])
+AC_INIT([Squid Web Proxy],[3.5.22],[http://bugs.squid-cache.org/],[squid])
AC_PREREQ(2.61)
AC_CONFIG_HEADERS([include/autoconf.h])
AC_CONFIG_AUX_DIR(cfgaux)
@@ -1778,7 +1778,7 @@
SQUID_CHECK_KRB5_FUNCS
fi
if test "x$KRB5LIBS" = "x"; then
- if test test "x$with_heimdal_krb5" = "xyes"; then
+ if test "x$with_heimdal_krb5" = "xyes"; then
AC_MSG_ERROR([Required Heimdal Kerberos library not found])
else
AC_MSG_WARN([Heimdal Kerberos library not found])
@@ -1848,7 +1848,7 @@
SQUID_DEFINE_BOOL(HAVE_KRB5,$squid_cv_working_krb5,[KRB5 support])
fi
if test "x$KRB5LIBS" = "x"; then
- if test test "x$with_gnugss" = "xyes"; then
+ if test "x$with_gnugss" = "xyes"; then
AC_MSG_ERROR([Required GNU GSS Kerberos library not found])
else
AC_MSG_WARN([GNU GSS Kerberos library not found])
diff -u -r -N squid-3.5.21/doc/release-notes/release-3.5.html squid-3.5.22/doc/release-notes/release-3.5.html
--- squid-3.5.21/doc/release-notes/release-3.5.html 2016-09-09 08:06:08.000000000 +1200
+++ squid-3.5.22/doc/release-notes/release-3.5.html 2016-10-10 12:34:07.000000000 +1300
@@ -2,10 +2,10 @@
- Squid 3.5.21 release notes
+ Squid 3.5.22 release notes
-Squid 3.5.21 release notes
+Squid 3.5.22 release notes
Squid Developers
@@ -64,7 +64,7 @@
-The Squid Team are pleased to announce the release of Squid-3.5.21.
+The Squid Team are pleased to announce the release of Squid-3.5.22.
This new release is available for download from
http://www.squid-cache.org/Versions/v3/3.5/ or the
mirrors.
diff -u -r -N squid-3.5.21/helpers/basic_auth/DB/basic_db_auth.8 squid-3.5.22/helpers/basic_auth/DB/basic_db_auth.8
--- squid-3.5.21/helpers/basic_auth/DB/basic_db_auth.8 2016-09-09 08:06:12.000000000 +1200
+++ squid-3.5.22/helpers/basic_auth/DB/basic_db_auth.8 2016-10-10 12:34:14.000000000 +1300
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29)
+.\" Automatically generated by Pod::Man 4.08 (Pod::Simple 3.32)
.\"
.\" Standard preamble:
.\" ========================================================================
@@ -46,7 +46,7 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
-.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
@@ -54,20 +54,16 @@
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
-.nr rF 0
-.if \n(.g .if rF .nr rF 1
-.if (\n(rF:(\n(.g==0)) \{
-. if \nF \{
-. de IX
-. tm Index:\\$1\t\\n%\t"\\$2"
+.if !\nF .nr F 0
+.if \nF>0 \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
..
-. if !\nF==2 \{
-. nr % 0
-. nr F 2
-. \}
+. if !\nF==2 \{\
+. nr % 0
+. nr F 2
. \}
.\}
-.rr rF
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts.
@@ -133,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BASIC_DB_AUTH 8"
-.TH BASIC_DB_AUTH 8 "2016-09-08" "perl v5.22.2" "User Contributed Perl Documentation"
+.TH BASIC_DB_AUTH 8 "2016-10-09" "perl v5.24.1" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
@@ -191,7 +187,7 @@
Keep a persistent database connection open between queries.
.IP "\fB\-\-joomla\fR" 12
.IX Item "--joomla"
-Tells helper that user database is Joomla \s-1DB. \s0 So their unusual salt
+Tells helper that user database is Joomla \s-1DB.\s0 So their unusual salt
hashing is understood.
.SH "AUTHOR"
.IX Header "AUTHOR"
@@ -230,7 +226,7 @@
Report ideas for new improvements to the \fISquid Developers mailing list
.SH "SEE ALSO"
.IX Header "SEE ALSO"
-squid (8), \s-1GPL \\fIs0\fR\|(7),
+squid (8), \s-1GPL\s0 (7),
.PP
The Squid \s-1FAQ\s0 wiki http://wiki.squid\-cache.org/SquidFaq
.PP
diff -u -r -N squid-3.5.21/helpers/basic_auth/MSNT-multi-domain/basic_msnt_multi_domain_auth.8 squid-3.5.22/helpers/basic_auth/MSNT-multi-domain/basic_msnt_multi_domain_auth.8
--- squid-3.5.21/helpers/basic_auth/MSNT-multi-domain/basic_msnt_multi_domain_auth.8 2016-09-09 08:06:18.000000000 +1200
+++ squid-3.5.22/helpers/basic_auth/MSNT-multi-domain/basic_msnt_multi_domain_auth.8 2016-10-10 12:34:22.000000000 +1300
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29)
+.\" Automatically generated by Pod::Man 4.08 (Pod::Simple 3.32)
.\"
.\" Standard preamble:
.\" ========================================================================
@@ -46,7 +46,7 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
-.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
@@ -54,20 +54,16 @@
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
-.nr rF 0
-.if \n(.g .if rF .nr rF 1
-.if (\n(rF:(\n(.g==0)) \{
-. if \nF \{
-. de IX
-. tm Index:\\$1\t\\n%\t"\\$2"
+.if !\nF .nr F 0
+.if \nF>0 \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
..
-. if !\nF==2 \{
-. nr % 0
-. nr F 2
-. \}
+. if !\nF==2 \{\
+. nr % 0
+. nr F 2
. \}
.\}
-.rr rF
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts.
@@ -133,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BASIC_MSNT_MULTI_DOMAIN_AUTH 1"
-.TH BASIC_MSNT_MULTI_DOMAIN_AUTH 1 "2016-09-08" "perl v5.22.2" "User Contributed Perl Documentation"
+.TH BASIC_MSNT_MULTI_DOMAIN_AUTH 1 "2016-10-09" "perl v5.24.1" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
@@ -205,7 +201,7 @@
Report ideas for new improvements to the \fISquid Developers mailing list
.SH "SEE ALSO"
.IX Header "SEE ALSO"
-squid (8), \s-1GPL \\fIs0\fR\|(7),
+squid (8), \s-1GPL\s0 (7),
.PP
The Squid \s-1FAQ\s0 wiki http://wiki.squid\-cache.org/SquidFaq
.PP
diff -u -r -N squid-3.5.21/helpers/basic_auth/POP3/basic_pop3_auth.8 squid-3.5.22/helpers/basic_auth/POP3/basic_pop3_auth.8
--- squid-3.5.21/helpers/basic_auth/POP3/basic_pop3_auth.8 2016-09-09 08:06:24.000000000 +1200
+++ squid-3.5.22/helpers/basic_auth/POP3/basic_pop3_auth.8 2016-10-10 12:34:31.000000000 +1300
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29)
+.\" Automatically generated by Pod::Man 4.08 (Pod::Simple 3.32)
.\"
.\" Standard preamble:
.\" ========================================================================
@@ -46,7 +46,7 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
-.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
@@ -54,20 +54,16 @@
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
-.nr rF 0
-.if \n(.g .if rF .nr rF 1
-.if (\n(rF:(\n(.g==0)) \{
-. if \nF \{
-. de IX
-. tm Index:\\$1\t\\n%\t"\\$2"
+.if !\nF .nr F 0
+.if \nF>0 \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
..
-. if !\nF==2 \{
-. nr % 0
-. nr F 2
-. \}
+. if !\nF==2 \{\
+. nr % 0
+. nr F 2
. \}
.\}
-.rr rF
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts.
@@ -133,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "BASIC_POP3_AUTH 8"
-.TH BASIC_POP3_AUTH 8 "2016-09-08" "perl v5.22.2" "User Contributed Perl Documentation"
+.TH BASIC_POP3_AUTH 8 "2016-10-09" "perl v5.24.1" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
@@ -202,7 +198,7 @@
Report ideas for new improvements to the \fISquid Developers mailing list
.SH "SEE ALSO"
.IX Header "SEE ALSO"
-squid (8), \s-1GPL \\fIs0\fR\|(7),
+squid (8), \s-1GPL\s0 (7),
.PP
The Squid \s-1FAQ\s0 wiki http://wiki.squid\-cache.org/SquidFaq
.PP
diff -u -r -N squid-3.5.21/helpers/external_acl/delayer/ext_delayer_acl.8 squid-3.5.22/helpers/external_acl/delayer/ext_delayer_acl.8
--- squid-3.5.21/helpers/external_acl/delayer/ext_delayer_acl.8 2016-09-09 08:06:41.000000000 +1200
+++ squid-3.5.22/helpers/external_acl/delayer/ext_delayer_acl.8 2016-10-10 12:34:52.000000000 +1300
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29)
+.\" Automatically generated by Pod::Man 4.08 (Pod::Simple 3.32)
.\"
.\" Standard preamble:
.\" ========================================================================
@@ -46,7 +46,7 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
-.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
@@ -54,20 +54,16 @@
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
-.nr rF 0
-.if \n(.g .if rF .nr rF 1
-.if (\n(rF:(\n(.g==0)) \{
-. if \nF \{
-. de IX
-. tm Index:\\$1\t\\n%\t"\\$2"
+.if !\nF .nr F 0
+.if \nF>0 \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
..
-. if !\nF==2 \{
-. nr % 0
-. nr F 2
-. \}
+. if !\nF==2 \{\
+. nr % 0
+. nr F 2
. \}
.\}
-.rr rF
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts.
@@ -133,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "EXT_DELAYER_ACL 8"
-.TH EXT_DELAYER_ACL 8 "2016-09-08" "perl v5.22.2" "User Contributed Perl Documentation"
+.TH EXT_DELAYER_ACL 8 "2016-10-09" "perl v5.24.1" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
@@ -225,7 +221,7 @@
Report ideas for new improvements to the \fISquid Developers mailing list
.SH "SEE ALSO"
.IX Header "SEE ALSO"
-squid (8), \s-1GPL \\fIs0\fR\|(7),
+squid (8), \s-1GPL\s0 (7),
.PP
The Squid \s-1FAQ\s0 wiki http://wiki.squid\-cache.org/SquidFaq
.PP
diff -u -r -N squid-3.5.21/helpers/external_acl/SQL_session/ext_sql_session_acl.8 squid-3.5.22/helpers/external_acl/SQL_session/ext_sql_session_acl.8
--- squid-3.5.21/helpers/external_acl/SQL_session/ext_sql_session_acl.8 2016-09-09 08:06:50.000000000 +1200
+++ squid-3.5.22/helpers/external_acl/SQL_session/ext_sql_session_acl.8 2016-10-10 12:35:06.000000000 +1300
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29)
+.\" Automatically generated by Pod::Man 4.08 (Pod::Simple 3.32)
.\"
.\" Standard preamble:
.\" ========================================================================
@@ -46,7 +46,7 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
-.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
@@ -54,20 +54,16 @@
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
-.nr rF 0
-.if \n(.g .if rF .nr rF 1
-.if (\n(rF:(\n(.g==0)) \{
-. if \nF \{
-. de IX
-. tm Index:\\$1\t\\n%\t"\\$2"
+.if !\nF .nr F 0
+.if \nF>0 \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
..
-. if !\nF==2 \{
-. nr % 0
-. nr F 2
-. \}
+. if !\nF==2 \{\
+. nr % 0
+. nr F 2
. \}
.\}
-.rr rF
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts.
@@ -133,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "EXT_SQL_SESSION_ACL 8"
-.TH EXT_SQL_SESSION_ACL 8 "2016-09-08" "perl v5.22.2" "User Contributed Perl Documentation"
+.TH EXT_SQL_SESSION_ACL 8 "2016-10-09" "perl v5.24.1" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
@@ -154,7 +150,7 @@
Taking an identity token to be validated (as determined by the external_acl_type format)
it returns a username or tag associated with the identity token passed in.
.PP
-Common forms of identifiers are \s-1IP\s0 address, \s-1EUI \s0(\s-1MAC\s0) address, passwords, or \s-1UUID\s0 tokens.
+Common forms of identifiers are \s-1IP\s0 address, \s-1EUI\s0 (\s-1MAC\s0) address, passwords, or \s-1UUID\s0 tokens.
.PP
This program uses Squid concurrency support.
.SH "OPTIONS"
@@ -225,7 +221,7 @@
Report ideas for new improvements to the \fISquid Developers mailing list
.SH "SEE ALSO"
.IX Header "SEE ALSO"
-squid (8), \s-1GPL \\fIs0\fR\|(7),
+squid (8), \s-1GPL\s0 (7),
.PP
The Squid \s-1FAQ\s0 wiki http://wiki.squid\-cache.org/SquidFaq
.PP
diff -u -r -N squid-3.5.21/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8 squid-3.5.22/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8
--- squid-3.5.21/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8 2016-09-09 08:06:55.000000000 +1200
+++ squid-3.5.22/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8 2016-10-10 12:35:12.000000000 +1300
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29)
+.\" Automatically generated by Pod::Man 4.08 (Pod::Simple 3.32)
.\"
.\" Standard preamble:
.\" ========================================================================
@@ -46,7 +46,7 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
-.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
@@ -54,20 +54,16 @@
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
-.nr rF 0
-.if \n(.g .if rF .nr rF 1
-.if (\n(rF:(\n(.g==0)) \{
-. if \nF \{
-. de IX
-. tm Index:\\$1\t\\n%\t"\\$2"
+.if !\nF .nr F 0
+.if \nF>0 \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
..
-. if !\nF==2 \{
-. nr % 0
-. nr F 2
-. \}
+. if !\nF==2 \{\
+. nr % 0
+. nr F 2
. \}
.\}
-.rr rF
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts.
@@ -133,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "EXT_WBINFO_GROUP_ACL 8"
-.TH EXT_WBINFO_GROUP_ACL 8 "2016-09-08" "perl v5.22.2" "User Contributed Perl Documentation"
+.TH EXT_WBINFO_GROUP_ACL 8 "2016-10-09" "perl v5.24.1" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff -u -r -N squid-3.5.21/helpers/log_daemon/DB/log_db_daemon.8 squid-3.5.22/helpers/log_daemon/DB/log_db_daemon.8
--- squid-3.5.21/helpers/log_daemon/DB/log_db_daemon.8 2016-09-09 08:06:58.000000000 +1200
+++ squid-3.5.22/helpers/log_daemon/DB/log_db_daemon.8 2016-10-10 12:35:15.000000000 +1300
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29)
+.\" Automatically generated by Pod::Man 4.08 (Pod::Simple 3.32)
.\"
.\" Standard preamble:
.\" ========================================================================
@@ -46,7 +46,7 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
-.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
@@ -54,20 +54,16 @@
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
-.nr rF 0
-.if \n(.g .if rF .nr rF 1
-.if (\n(rF:(\n(.g==0)) \{
-. if \nF \{
-. de IX
-. tm Index:\\$1\t\\n%\t"\\$2"
+.if !\nF .nr F 0
+.if \nF>0 \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
..
-. if !\nF==2 \{
-. nr % 0
-. nr F 2
-. \}
+. if !\nF==2 \{\
+. nr % 0
+. nr F 2
. \}
.\}
-.rr rF
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts.
@@ -133,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "LOG_DB_DAEMON 8"
-.TH LOG_DB_DAEMON 8 "2016-09-08" "perl v5.22.2" "User Contributed Perl Documentation"
+.TH LOG_DB_DAEMON 8 "2016-10-09" "perl v5.24.1" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
diff -u -r -N squid-3.5.21/helpers/storeid_rewrite/file/storeid_file_rewrite.8 squid-3.5.22/helpers/storeid_rewrite/file/storeid_file_rewrite.8
--- squid-3.5.21/helpers/storeid_rewrite/file/storeid_file_rewrite.8 2016-09-09 08:07:15.000000000 +1200
+++ squid-3.5.22/helpers/storeid_rewrite/file/storeid_file_rewrite.8 2016-10-10 12:35:38.000000000 +1300
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29)
+.\" Automatically generated by Pod::Man 4.08 (Pod::Simple 3.32)
.\"
.\" Standard preamble:
.\" ========================================================================
@@ -46,7 +46,7 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
-.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
@@ -54,20 +54,16 @@
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
-.nr rF 0
-.if \n(.g .if rF .nr rF 1
-.if (\n(rF:(\n(.g==0)) \{
-. if \nF \{
-. de IX
-. tm Index:\\$1\t\\n%\t"\\$2"
+.if !\nF .nr F 0
+.if \nF>0 \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
..
-. if !\nF==2 \{
-. nr % 0
-. nr F 2
-. \}
+. if !\nF==2 \{\
+. nr % 0
+. nr F 2
. \}
.\}
-.rr rF
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts.
@@ -133,7 +129,7 @@
.\" ========================================================================
.\"
.IX Title "STOREID_FILE_REWRITE 8"
-.TH STOREID_FILE_REWRITE 8 "2016-09-08" "perl v5.22.2" "User Contributed Perl Documentation"
+.TH STOREID_FILE_REWRITE 8 "2016-10-09" "perl v5.24.1" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
@@ -213,7 +209,7 @@
Report ideas for new improvements to the \fISquid Developers mailing list
.SH "SEE ALSO"
.IX Header "SEE ALSO"
-squid (8), \s-1GPL \\fIs0\fR\|(7),
+squid (8), \s-1GPL\s0 (7),
.PP
The Squid wiki http://wiki.squid\-cache.org/Features/StoreID
.PP
diff -u -r -N squid-3.5.21/include/version.h squid-3.5.22/include/version.h
--- squid-3.5.21/include/version.h 2016-09-09 07:00:42.000000000 +1200
+++ squid-3.5.22/include/version.h 2016-10-10 09:04:24.000000000 +1300
@@ -7,7 +7,7 @@
*/
#ifndef SQUID_RELEASE_TIME
-#define SQUID_RELEASE_TIME 1473360998
+#define SQUID_RELEASE_TIME 1476043069
#endif
/*
diff -u -r -N squid-3.5.21/RELEASENOTES.html squid-3.5.22/RELEASENOTES.html
--- squid-3.5.21/RELEASENOTES.html 2016-09-09 08:06:08.000000000 +1200
+++ squid-3.5.22/RELEASENOTES.html 2016-10-10 12:34:07.000000000 +1300
@@ -2,10 +2,10 @@
- Squid 3.5.21 release notes
+ Squid 3.5.22 release notes
-Squid 3.5.21 release notes
+Squid 3.5.22 release notes
Squid Developers
@@ -64,7 +64,7 @@
-The Squid Team are pleased to announce the release of Squid-3.5.21.
+The Squid Team are pleased to announce the release of Squid-3.5.22.
This new release is available for download from
http://www.squid-cache.org/Versions/v3/3.5/ or the
mirrors.
diff -u -r -N squid-3.5.21/src/adaptation/ecap/XactionRep.cc squid-3.5.22/src/adaptation/ecap/XactionRep.cc
--- squid-3.5.21/src/adaptation/ecap/XactionRep.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/adaptation/ecap/XactionRep.cc 2016-10-10 08:58:01.000000000 +1300
@@ -726,7 +726,7 @@
buf.append(" A?", 3);
}
- buf.Printf(" %s%u]", id.Prefix, id.value);
+ buf.Printf(" %s%u]", id.prefix(), id.value);
buf.terminate();
diff -u -r -N squid-3.5.21/src/adaptation/History.cc squid-3.5.22/src/adaptation/History.cc
--- squid-3.5.21/src/adaptation/History.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/adaptation/History.cc 2016-10-10 08:58:01.000000000 +1300
@@ -150,9 +150,9 @@
void Adaptation::History::recordMeta(const HttpHeader *lm)
{
lastMeta.clean();
- lastMeta.update(lm, NULL);
+ lastMeta.update(lm);
- allMeta.update(lm, NULL);
+ allMeta.update(lm);
allMeta.compact();
}
diff -u -r -N squid-3.5.21/src/adaptation/icap/ModXact.cc squid-3.5.22/src/adaptation/icap/ModXact.cc
--- squid-3.5.21/src/adaptation/icap/ModXact.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/adaptation/icap/ModXact.cc 2016-10-10 08:58:01.000000000 +1300
@@ -1259,31 +1259,32 @@
void Adaptation::Icap::ModXact::finalizeLogInfo()
{
- HttpRequest * request_ = NULL;
- HttpRequest * adapted_request_ = NULL;
- HttpReply * reply_ = NULL;
- request_ = (virgin.cause? virgin.cause: dynamic_cast(virgin.header));
+ HttpRequest *adapted_request_ = NULL;
+ HttpReply *adapted_reply_ = NULL;
+ HttpRequest *virgin_request_ = const_cast(&virginRequest());
if (!(adapted_request_ = dynamic_cast(adapted.header))) {
- adapted_request_ = request_;
- reply_ = dynamic_cast(adapted.header);
+ // if the request was not adapted, use virgin request to simplify
+ // the code further below
+ adapted_request_ = virgin_request_;
+ adapted_reply_ = dynamic_cast(adapted.header);
}
- Adaptation::Icap::History::Pointer h = (request_ ? request_->icapHistory() : NULL);
+ Adaptation::Icap::History::Pointer h = virgin_request_->icapHistory();
Must(h != NULL); // ICAPXaction::maybeLog calls only if there is a log
al.icp.opcode = ICP_INVALID;
al.url = h->log_uri.termedBuf();
const Adaptation::Icap::ServiceRep &s = service();
al.icap.reqMethod = s.cfg().method;
- al.cache.caddr = request_->client_addr;
+ al.cache.caddr = virgin_request_->client_addr;
- al.request = request_;
+ al.request = virgin_request_;
HTTPMSGLOCK(al.request);
al.adapted_request = adapted_request_;
HTTPMSGLOCK(al.adapted_request);
- if (reply_) {
- al.reply = reply_;
+ if (adapted_reply_) {
+ al.reply = adapted_reply_;
HTTPMSGLOCK(al.reply);
} else
al.reply = NULL;
@@ -1296,25 +1297,29 @@
al.cache.ssluser = h->ssluser.termedBuf();
#endif
al.cache.code = h->logType;
- // XXX: should use icap-specific counters instead ?
- al.http.clientRequestSz.payloadData = h->req_sz;
+
+ const HttpMsg *virgin_msg = dynamic_cast(virgin.header);
+ if (!virgin_msg)
+ virgin_msg = virgin_request_;
+ assert(virgin_msg != virgin.cause);
+ al.http.clientRequestSz.header = virgin_msg->hdr_sz;
+ al.http.clientRequestSz.payloadData = virgin_msg->body_pipe->producedSize();
// leave al.icap.bodyBytesRead negative if no body
if (replyHttpHeaderSize >= 0 || replyHttpBodySize >= 0) {
const int64_t zero = 0; // to make max() argument types the same
- al.icap.bodyBytesRead =
- max(zero, replyHttpHeaderSize) + max(zero, replyHttpBodySize);
+ const uint64_t headerSize = max(zero, replyHttpHeaderSize);
+ const uint64_t bodySize = max(zero, replyHttpBodySize);
+ al.icap.bodyBytesRead = headerSize + bodySize;
+ al.http.clientReplySz.header = headerSize;
+ al.http.clientReplySz.payloadData = bodySize;
}
- if (reply_) {
- al.http.code = reply_->sline.status();
- al.http.content_type = reply_->content_type.termedBuf();
- if (replyHttpBodySize >= 0) {
- // XXX: should use icap-specific counters instead ?
- al.http.clientReplySz.payloadData = replyHttpBodySize;
- al.http.clientReplySz.header = reply_->hdr_sz;
+ if (adapted_reply_) {
+ al.http.code = adapted_reply_->sline.status();
+ al.http.content_type = adapted_reply_->content_type.termedBuf();
+ if (replyHttpBodySize >= 0)
al.cache.highOffset = replyHttpBodySize;
- }
//don't set al.cache.objectSize because it hasn't exist yet
Packer p;
@@ -1323,7 +1328,7 @@
mb.init();
packerToMemInit(&p, &mb);
- reply_->header.packInto(&p);
+ adapted_reply_->header.packInto(&p);
al.headers.reply = xstrdup(mb.buf);
packerClean(&p);
diff -u -r -N squid-3.5.21/src/adaptation/icap/Xaction.cc squid-3.5.22/src/adaptation/icap/Xaction.cc
--- squid-3.5.21/src/adaptation/icap/Xaction.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/adaptation/icap/Xaction.cc 2016-10-10 08:58:01.000000000 +1300
@@ -598,9 +598,7 @@
fillPendingStatus(buf);
buf.append("/", 1);
fillDoneStatus(buf);
-
- buf.Printf(" %s%u]", id.Prefix, id.value);
-
+ buf.Printf(" %s%u]", id.prefix(), id.value);
buf.terminate();
return buf.content();
diff -u -r -N squid-3.5.21/src/base/AsyncJob.cc squid-3.5.22/src/base/AsyncJob.cc
--- squid-3.5.21/src/base/AsyncJob.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/base/AsyncJob.cc 2016-10-10 08:58:01.000000000 +1300
@@ -164,7 +164,7 @@
buf.Printf("Stopped, reason:");
buf.Printf("%s",stopReason);
}
- buf.Printf(" %s%u]", id.Prefix, id.value);
+ buf.Printf(" %s%u]", id.prefix(), id.value);
buf.terminate();
return buf.content();
diff -u -r -N squid-3.5.21/src/base/InstanceId.h squid-3.5.22/src/base/InstanceId.h
--- squid-3.5.21/src/base/InstanceId.h 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/base/InstanceId.h 2016-10-10 08:58:01.000000000 +1300
@@ -25,35 +25,41 @@
public:
typedef unsigned int Value; ///< id storage type; \todo: parameterize?
- InstanceId(): value(++Last ? Last : ++Last) {}
+ InstanceId(): value(0) {change();}
operator Value() const { return value; }
bool operator ==(const InstanceId &o) const { return value == o.value; }
bool operator !=(const InstanceId &o) const { return !(*this == o); }
- void change() {value = ++Last ? Last : ++Last;}
+ void change();
- /// prints Prefix followed by ID value; \todo: use HEX for value printing?
+ /// prints class-pecific prefix followed by ID value; \todo: use HEX for value printing?
std::ostream &print(std::ostream &os) const;
+ /// returns the class-pecific prefix
+ const char * const prefix() const;
+
public:
- static const char *Prefix; ///< Class shorthand string for debugging
Value value; ///< instance identifier
private:
InstanceId(const InstanceId& right); ///< not implemented; IDs are unique
InstanceId& operator=(const InstanceId &right); ///< not implemented
-
-private:
- static Value Last; ///< the last used ID value
};
/// convenience macro to instantiate Class-specific stuff in .cc files
-#define InstanceIdDefinitions(Class, prefix) \
- template<> const char *InstanceId::Prefix = prefix; \
- template<> InstanceId::Value InstanceId::Last = 0; \
+#define InstanceIdDefinitions(Class, pfx) \
+ template<> const char * const \
+ InstanceId::prefix() const { \
+ return pfx; \
+ } \
template<> std::ostream & \
InstanceId::print(std::ostream &os) const { \
- return os << Prefix << value; \
+ return os << pfx << value; \
+ } \
+ template<> void \
+ InstanceId::change() { \
+ static InstanceId::Value Last = 0; \
+ value = ++Last ? Last : ++Last; \
}
/// print the id
diff -u -r -N squid-3.5.21/src/cache_cf.cc squid-3.5.22/src/cache_cf.cc
--- squid-3.5.21/src/cache_cf.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/cache_cf.cc 2016-10-10 08:58:01.000000000 +1300
@@ -849,7 +849,7 @@
if (pwd->pw_dir && *pwd->pw_dir) {
// putenv() leaks by design; avoid leaks when nothing changes
static SBuf lastDir;
- if (lastDir.isEmpty() || !lastDir.cmp(pwd->pw_dir)) {
+ if (lastDir.isEmpty() || lastDir.cmp(pwd->pw_dir) != 0) {
lastDir = pwd->pw_dir;
int len = strlen(pwd->pw_dir) + 6;
char *env_str = (char *)xcalloc(len, 1);
diff -u -r -N squid-3.5.21/src/cf.data.pre squid-3.5.22/src/cf.data.pre
--- squid-3.5.21/src/cf.data.pre 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/cf.data.pre 2016-10-10 08:58:01.000000000 +1300
@@ -4427,13 +4427,35 @@
ICAP transaction log lines will correspond to a single access
log line.
- ICAP log uses logformat codes that make sense for an ICAP
- transaction. Header-related codes are applied to the HTTP header
- embedded in an ICAP server response, with the following caveats:
- For REQMOD, there is no HTTP response header unless the ICAP
- server performed request satisfaction. For RESPMOD, the HTTP
- request header is the header sent to the ICAP server. For
- OPTIONS, there are no HTTP headers.
+ ICAP log supports many access.log logformat %codes. In ICAP context,
+ HTTP message-related %codes are applied to the HTTP message embedded
+ in an ICAP message. Logformat "%http::>..." codes are used for HTTP
+ messages embedded in ICAP requests while "%http::<..." codes are used
+ for HTTP messages embedded in ICAP responses. For example:
+
+ http::>h To-be-adapted HTTP message headers sent by Squid to
+ the ICAP service. For REQMOD transactions, these are
+ HTTP request headers. For RESPMOD, these are HTTP
+ response headers, but Squid currently cannot log them
+ (i.e., %http::>h will expand to "-" for RESPMOD).
+
+ http::st Bytes sent to the ICAP server (TCP payload
- only; i.e., what Squid writes to the socket).
+ icap::>st The total size of the ICAP request sent to the ICAP
+ server (ICAP headers + ICAP body), including chunking
+ metadata (if any).
+
+ icap::a %icap::to/%03icap::Hs %icap::A %icap::to/%03icap::Hs %icap::http.method = request->method;
aLogEntry->http.version = request->http_ver;
aLogEntry->hier = request->hier;
- if (request->content_length > 0) // negative when no body or unknown length
- aLogEntry->http.clientRequestSz.payloadData += request->content_length; // XXX: actually adaptedRequest payload size ??
aLogEntry->cache.extuser = request->extacl_user.termedBuf();
// Adapted request, if any, inherits and then collects all the stats, but
@@ -593,6 +591,9 @@
al->cache.objectSize = loggingEntry()->contentLen(); // payload duplicate ?? with or without TE ?
al->http.clientRequestSz.header = req_sz;
+ // the virgin request is saved to al->request
+ if (al->request && al->request->body_pipe != NULL)
+ al->http.clientRequestSz.payloadData = al->request->body_pipe->producedSize();
al->http.clientReplySz.header = out.headers_sz;
// XXX: calculate without payload encoding or headers !!
al->http.clientReplySz.payloadData = out.size - out.headers_sz; // pretend its all un-encoded data for now.
@@ -1236,7 +1237,7 @@
/* got modification time? */
if (spec.time >= 0) {
- return http->storeEntry()->lastmod <= spec.time;
+ return !http->storeEntry()->modifiedSince(spec.time);
}
assert(0); /* should not happen */
@@ -2744,6 +2745,7 @@
request->my_addr = conn->clientConnection->local;
request->myportname = conn->port->name;
request->http_ver = http_ver;
+ request->hdr_sz = http->req_sz;
// Link this HttpRequest to ConnStateData relatively early so the following complex handling can use it
// TODO: this effectively obsoletes a lot of conn->FOO copying. That needs cleaning up later.
diff -u -r -N squid-3.5.21/src/client_side_reply.cc squid-3.5.22/src/client_side_reply.cc
--- squid-3.5.21/src/client_side_reply.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/client_side_reply.cc 2016-10-10 08:58:01.000000000 +1300
@@ -72,7 +72,8 @@
HTTPMSGUNLOCK(reply);
}
-clientReplyContext::clientReplyContext(ClientHttpRequest *clientContext) : http (cbdataReference(clientContext)), old_entry (NULL), old_sc(NULL), deleting(false)
+clientReplyContext::clientReplyContext(ClientHttpRequest *clientContext) : http (cbdataReference(clientContext)), old_entry (NULL), old_sc(NULL), deleting(false),
+ collapsedRevalidation(crNone)
{}
/** Create an error in the store awaiting the client side to read it.
@@ -245,9 +246,9 @@
clientReplyContext::processExpired()
{
const char *url = storeId();
- StoreEntry *entry = NULL;
debugs(88, 3, "clientReplyContext::processExpired: '" << http->uri << "'");
- assert(http->storeEntry()->lastmod >= 0);
+ const time_t lastmod = http->storeEntry()->lastModified();
+ assert(lastmod >= 0);
/*
* check if we are allowed to contact other servers
* @?@: Instead of a 504 (Gateway Timeout) reply, we may want to return
@@ -267,16 +268,43 @@
#endif
/* Prepare to make a new temporary request */
saveState();
- entry = storeCreateEntry(url,
- http->log_uri, http->request->flags, http->request->method);
- /* NOTE, don't call StoreEntry->lock(), storeCreateEntry() does it */
+
+ // TODO: support collapsed revalidation of Vary-controlled entries
+ const bool collapsingAllowed = Config.onoff.collapsed_forwarding &&
+ !Store::Root().smpAware() &&
+ http->request->vary_headers.isEmpty();
+
+ StoreEntry *entry = nullptr;
+ if (collapsingAllowed) {
+ if ((entry = storeGetPublicByRequest(http->request, ksRevalidation)))
+ entry->lock("clientReplyContext::processExpired#alreadyRevalidating");
+ }
+
+ if (entry) {
+ debugs(88, 5, "collapsed on existing revalidation entry: " << *entry);
+ collapsedRevalidation = crSlave;
+ } else {
+ entry = storeCreateEntry(url,
+ http->log_uri, http->request->flags, http->request->method);
+ /* NOTE, don't call StoreEntry->lock(), storeCreateEntry() does it */
+
+ if (collapsingAllowed) {
+ debugs(88, 5, "allow other revalidation requests to collapse on " << *entry);
+ Store::Root().allowCollapsing(entry, http->request->flags,
+ http->request->method);
+ collapsedRevalidation = crInitiator;
+ } else {
+ collapsedRevalidation = crNone;
+ }
+ }
+
sc = storeClientListAdd(entry, this);
#if USE_DELAY_POOLS
/* delay_id is already set on original store client */
sc->setDelayId(DelayId::DelayClient(http));
#endif
- http->request->lastmod = old_entry->lastmod;
+ http->request->lastmod = lastmod;
if (!http->request->header.has(HDR_IF_NONE_MATCH)) {
ETag etag = {NULL, -1}; // TODO: make that a default ETag constructor
@@ -284,17 +312,19 @@
http->request->etag = etag.str;
}
- debugs(88, 5, "clientReplyContext::processExpired : lastmod " << entry->lastmod );
+ debugs(88, 5, "lastmod " << entry->lastModified());
http->storeEntry(entry);
assert(http->out.offset == 0);
assert(http->request->clientConnectionManager == http->getConn());
- /*
- * A refcounted pointer so that FwdState stays around as long as
- * this clientReplyContext does
- */
- Comm::ConnectionPointer conn = http->getConn() != NULL ? http->getConn()->clientConnection : NULL;
- FwdState::Start(conn, http->storeEntry(), http->request, http->al);
+ if (collapsedRevalidation != crSlave) {
+ /*
+ * A refcounted pointer so that FwdState stays around as long as
+ * this clientReplyContext does
+ */
+ Comm::ConnectionPointer conn = http->getConn() != NULL ? http->getConn()->clientConnection : NULL;
+ FwdState::Start(conn, http->storeEntry(), http->request, http->al);
+ }
/* Register with storage manager to receive updates when data comes in. */
@@ -358,7 +388,7 @@
if (deleting)
return;
- debugs(88, 3, "handleIMSReply: " << http->storeEntry()->url() << ", " << (long unsigned) result.length << " bytes" );
+ debugs(88, 3, http->storeEntry()->url() << ", " << (long unsigned) result.length << " bytes");
if (http->storeEntry() == NULL)
return;
@@ -373,7 +403,7 @@
// request to origin was aborted
if (EBIT_TEST(http->storeEntry()->flags, ENTRY_ABORTED)) {
- debugs(88, 3, "handleIMSReply: request to origin aborted '" << http->storeEntry()->url() << "', sending old entry to client" );
+ debugs(88, 3, "request to origin aborted '" << http->storeEntry()->url() << "', sending old entry to client");
http->logType = LOG_TCP_REFRESH_FAIL_OLD;
sendClientOldEntry();
}
@@ -391,13 +421,13 @@
// if client sent IMS
- if (http->request->flags.ims && !old_entry->modifiedSince(http->request)) {
+ if (http->request->flags.ims && !old_entry->modifiedSince(http->request->ims, http->request->imslen)) {
// forward the 304 from origin
- debugs(88, 3, "handleIMSReply: origin replied 304, revalidating existing entry and forwarding 304 to client");
+ debugs(88, 3, "origin replied 304, revalidating existing entry and forwarding 304 to client");
sendClientUpstreamResponse();
} else {
// send existing entry, it's still valid
- debugs(88, 3, "handleIMSReply: origin replied 304, revalidating existing entry and sending " <<
+ debugs(88, 3, "origin replied 304, revalidating existing entry and sending " <<
old_rep->sline.status() << " to client");
sendClientOldEntry();
}
@@ -405,22 +435,37 @@
// origin replied with a non-error code
else if (status > Http::scNone && status < Http::scInternalServerError) {
- // forward response from origin
- http->logType = LOG_TCP_REFRESH_MODIFIED;
- debugs(88, 3, "handleIMSReply: origin replied " << status << ", replacing existing entry and forwarding to client");
- sendClientUpstreamResponse();
+ const HttpReply *new_rep = http->storeEntry()->getReply();
+ // RFC 7234 section 4: a cache MUST use the most recent response
+ // (as determined by the Date header field)
+ if (new_rep->olderThan(old_rep)) {
+ http->logType = LOG_TCP_REFRESH_IGNORED;
+ debugs(88, 3, "origin replied " << status <<
+ " but with an older date header, sending old entry (" <<
+ old_rep->sline.status() << ") to client");
+ sendClientOldEntry();
+ } else {
+ http->logType = LOG_TCP_REFRESH_MODIFIED;
+ debugs(88, 3, "origin replied " << status <<
+ ", replacing existing entry and forwarding to client");
+
+ if (collapsedRevalidation)
+ http->storeEntry()->clearPublicKeyScope();
+
+ sendClientUpstreamResponse();
+ }
}
// origin replied with an error
else if (http->request->flags.failOnValidationError) {
http->logType = LOG_TCP_REFRESH_FAIL_ERR;
- debugs(88, 3, "handleIMSReply: origin replied with error " << status <<
+ debugs(88, 3, "origin replied with error " << status <<
", forwarding to client due to fail_on_validation_err");
sendClientUpstreamResponse();
} else {
// ignore and let client have old entry
http->logType = LOG_TCP_REFRESH_FAIL_OLD;
- debugs(88, 3, "handleIMSReply: origin replied with error " <<
+ debugs(88, 3, "origin replied with error " <<
status << ", sending old entry (" << old_rep->sline.status() << ") to client");
sendClientOldEntry();
}
@@ -563,11 +608,12 @@
*/
r->flags.needValidation = true;
- if (e->lastmod < 0) {
- debugs(88, 3, "validate HIT object? NO. Missing Last-Modified header. Do MISS.");
+ if (e->lastModified() < 0) {
+ debugs(88, 3, "validate HIT object? NO. Can't calculate entry modification time. Do MISS.");
/*
- * Previous reply didn't have a Last-Modified header,
- * we cannot revalidate it.
+ * We cannot revalidate entries without knowing their
+ * modification time.
+ * XXX: BUG 1890 objects without Date do not get one added.
*/
http->logType = LOG_TCP_MISS;
processMiss();
@@ -756,7 +802,7 @@
if (r.flags.ims) {
// handle If-Modified-Since requests from the client
- if (e->modifiedSince(&r)) {
+ if (e->modifiedSince(r.ims, r.imslen)) {
http->logType = LOG_TCP_IMS_HIT;
sendMoreData(result);
return;
diff -u -r -N squid-3.5.21/src/client_side_reply.h squid-3.5.22/src/client_side_reply.h
--- squid-3.5.21/src/client_side_reply.h 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/client_side_reply.h 2016-10-10 08:58:01.000000000 +1300
@@ -133,6 +133,14 @@
store_client *old_sc; /* ... for entry to be validated */
bool deleting;
+ typedef enum {
+ crNone = 0, ///< collapsed revalidation is not allowed for this context
+ crInitiator, ///< we initiated collapsed revalidation request
+ crSlave ///< we collapsed on the existing revalidation request
+ } CollapsedRevalidation;
+
+ CollapsedRevalidation collapsedRevalidation;
+
CBDATA_CLASS2(clientReplyContext);
};
diff -u -r -N squid-3.5.21/src/client_side_request.cc squid-3.5.22/src/client_side_request.cc
--- squid-3.5.21/src/client_side_request.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/client_side_request.cc 2016-10-10 08:58:01.000000000 +1300
@@ -336,7 +336,7 @@
* correctness.
*/
if (header)
- request->header.update(header, NULL);
+ request->header.update(header);
http->log_uri = xstrdup(urlCanonicalClean(request));
diff -u -r -N squid-3.5.21/src/errorpage.cc squid-3.5.22/src/errorpage.cc
--- squid-3.5.21/src/errorpage.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/errorpage.cc 2016-10-10 08:58:01.000000000 +1300
@@ -358,7 +358,6 @@
bool strHdrAcptLangGetItem(const String &hdr, char *lang, int langLen, size_t &pos)
{
while (pos < hdr.size()) {
- char *dt = lang;
/* skip any initial whitespace. */
while (pos < hdr.size() && xisspace(hdr[pos]))
@@ -372,6 +371,7 @@
* with preference given to an exact match.
*/
bool invalid_byte = false;
+ char *dt = lang;
while (pos < hdr.size() && hdr[pos] != ';' && hdr[pos] != ',' && !xisspace(hdr[pos]) && dt < (lang + (langLen -1)) ) {
if (!invalid_byte) {
#if USE_HTTP_VIOLATIONS
@@ -391,7 +391,6 @@
++pos;
}
*dt = '\0'; // nul-terminated the filename content string before system use.
- ++dt;
// if we terminated the tag on garbage or ';' we need to skip to the next ',' or end of header.
while (pos < hdr.size() && hdr[pos] != ',')
@@ -400,7 +399,7 @@
if (pos < hdr.size() && hdr[pos] == ',')
++pos;
- debugs(4, 9, HERE << "STATE: dt='" << dt << "', lang='" << lang << "', pos=" << pos << ", buf='" << ((pos < hdr.size()) ? hdr.substr(pos,hdr.size()) : "") << "'");
+ debugs(4, 9, "STATE: lang=" << lang << ", pos=" << pos << ", buf='" << ((pos < hdr.size()) ? hdr.substr(pos,hdr.size()) : "") << "'");
/* if we found anything we might use, try it. */
if (*lang != '\0' && !invalid_byte)
diff -u -r -N squid-3.5.21/src/esi/Include.cc squid-3.5.22/src/esi/Include.cc
--- squid-3.5.21/src/esi/Include.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/esi/Include.cc 2016-10-10 08:58:01.000000000 +1300
@@ -279,7 +279,7 @@
void
ESIInclude::prepareRequestHeaders(HttpHeader &tempheaders, ESIVarState *vars)
{
- tempheaders.update (&vars->header(), NULL);
+ tempheaders.update (&vars->header());
tempheaders.removeHopByHopEntries();
}
diff -u -r -N squid-3.5.21/src/format/Format.cc squid-3.5.22/src/format/Format.cc
--- squid-3.5.21/src/format/Format.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/format/Format.cc 2016-10-10 08:58:01.000000000 +1300
@@ -309,6 +309,38 @@
*p = '\0';
}
+/// XXX: Misnamed. TODO: Split reply;
+#if USE_ADAPTATION
+ // al->icap.reqMethod is methodNone in access.log context
+ if (!msg && al->icap.reqMethod == Adaptation::methodReqmod)
+ msg = al->adapted_request;
+#endif
+ return msg;
+}
+
+/// XXX: Misnamed. See actualReplyHeader().
+/// \return HttpRequest or HttpReply for %http::>h.
+static const HttpMsg *
+actualRequestHeader(const AccessLogEntry::Pointer &al)
+{
+#if USE_ADAPTATION
+ // al->icap.reqMethod is methodNone in access.log context
+ if (al->icap.reqMethod == Adaptation::methodRespmod) {
+ // XXX: for now AccessLogEntry lacks virgin response headers
+ return NULL;
+ }
+#endif
+ return al->request;
+}
+
void
Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logSequenceNumber) const
{
@@ -547,8 +579,8 @@
case LFT_REQUEST_HEADER:
- if (al->request)
- sb = al->request->header.getByName(fmt->data.header.header);
+ if (const HttpMsg *msg = actualRequestHeader(al))
+ sb = msg->header.getByName(fmt->data.header.header);
out = sb.termedBuf();
@@ -567,15 +599,15 @@
break;
- case LFT_REPLY_HEADER:
- if (al->reply)
- sb = al->reply->header.getByName(fmt->data.header.header);
+ case LFT_REPLY_HEADER: {
+ if (const HttpMsg *msg = actualReplyHeader(al))
+ sb = msg->header.getByName(fmt->data.header.header);
out = sb.termedBuf();
quote = 1;
-
- break;
+ }
+ break;
#if USE_ADAPTATION
case LFT_ADAPTATION_SUM_XACT_TIMES:
@@ -757,8 +789,8 @@
break;
#endif
case LFT_REQUEST_HEADER_ELEM:
- if (al->request)
- sb = al->request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
+ if (const HttpMsg *msg = actualRequestHeader(al))
+ sb = msg->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
out = sb.termedBuf();
@@ -776,18 +808,27 @@
break;
- case LFT_REPLY_HEADER_ELEM:
- if (al->reply)
- sb = al->reply->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
+ case LFT_REPLY_HEADER_ELEM: {
+ if (const HttpMsg *msg = actualReplyHeader(al))
+ sb = msg->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator);
out = sb.termedBuf();
quote = 1;
-
- break;
+ }
+ break;
case LFT_REQUEST_ALL_HEADERS:
- out = al->headers.request;
+#if USE_ADAPTATION
+ if (al->icap.reqMethod == Adaptation::methodRespmod) {
+ // XXX: since AccessLogEntry::Headers lacks virgin response
+ // headers, do nothing for now
+ out = NULL;
+ } else
+#endif
+ {
+ out = al->headers.request;
+ }
quote = 1;
@@ -802,6 +843,10 @@
case LFT_REPLY_ALL_HEADERS:
out = al->headers.reply;
+#if USE_ADAPTATION
+ if (!out && al->icap.reqMethod == Adaptation::methodReqmod)
+ out = al->headers.adapted_request;
+#endif
quote = 1;
diff -u -r -N squid-3.5.21/src/fs/rock/RockSwapDir.cc squid-3.5.22/src/fs/rock/RockSwapDir.cc
--- squid-3.5.21/src/fs/rock/RockSwapDir.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/fs/rock/RockSwapDir.cc 2016-10-10 08:58:01.000000000 +1300
@@ -134,7 +134,7 @@
e.lastref = basics.lastref;
e.timestamp = basics.timestamp;
e.expires = basics.expires;
- e.lastmod = basics.lastmod;
+ e.lastModified(basics.lastmod);
e.refcount = basics.refcount;
e.flags = basics.flags;
diff -u -r -N squid-3.5.21/src/fs/rock/RockSwapDir.h squid-3.5.22/src/fs/rock/RockSwapDir.h
--- squid-3.5.21/src/fs/rock/RockSwapDir.h 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/fs/rock/RockSwapDir.h 2016-10-10 08:58:01.000000000 +1300
@@ -48,6 +48,7 @@
virtual void swappedOut(const StoreEntry &e);
virtual void create();
virtual void parse(int index, char *path);
+ virtual bool smpAware() const { return true; }
// temporary path to the shared memory map of first slots of cached entries
SBuf inodeMapPath() const;
diff -u -r -N squid-3.5.21/src/fs/ufs/RebuildState.cc squid-3.5.22/src/fs/ufs/RebuildState.cc
--- squid-3.5.21/src/fs/ufs/RebuildState.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/fs/ufs/RebuildState.cc 2016-10-10 08:58:01.000000000 +1300
@@ -74,9 +74,11 @@
Fs::Ufs::RebuildState::RebuildStep(void *data)
{
RebuildState *rb = (RebuildState *)data;
- rb->rebuildStep();
+ if (!reconfiguring)
+ rb->rebuildStep();
- if (!rb->isDone())
+ // delay storeRebuildComplete() when reconfiguring to protect storeCleanup()
+ if (!rb->isDone() || reconfiguring)
eventAdd("storeRebuild", RebuildStep, rb, 0.01, 1);
else {
-- StoreController::store_dirs_rebuilding;
@@ -199,7 +201,7 @@
tmpe.expires,
tmpe.timestamp,
tmpe.lastref,
- tmpe.lastmod,
+ tmpe.lastModified(),
tmpe.refcount, /* refcount */
tmpe.flags, /* flags */
(int) flags.clean));
@@ -326,7 +328,7 @@
currentEntry()->lastref = swapData.timestamp;
currentEntry()->timestamp = swapData.timestamp;
currentEntry()->expires = swapData.expires;
- currentEntry()->lastmod = swapData.lastmod;
+ currentEntry()->lastModified(swapData.lastmod);
currentEntry()->flags = swapData.flags;
currentEntry()->refcount += swapData.refcount;
sd->dereference(*currentEntry(), false);
diff -u -r -N squid-3.5.21/src/fs/ufs/UFSStoreState.cc squid-3.5.22/src/fs/ufs/UFSStoreState.cc
--- squid-3.5.21/src/fs/ufs/UFSStoreState.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/fs/ufs/UFSStoreState.cc 2016-10-10 08:58:01.000000000 +1300
@@ -421,7 +421,7 @@
if (flags.write_draining)
return;
- if (!theFile->canWrite())
+ if (!theFile || !theFile->canWrite())
return;
flags.write_draining = true;
diff -u -r -N squid-3.5.21/src/fs/ufs/UFSSwapDir.cc squid-3.5.22/src/fs/ufs/UFSSwapDir.cc
--- squid-3.5.21/src/fs/ufs/UFSSwapDir.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/fs/ufs/UFSSwapDir.cc 2016-10-10 08:58:01.000000000 +1300
@@ -87,7 +87,7 @@
s.timestamp = e.timestamp;
s.lastref = e.lastref;
s.expires = e.expires;
- s.lastmod = e.lastmod;
+ s.lastmod = e.lastModified();
s.swap_file_sz = e.swap_file_sz;
s.refcount = e.refcount;
s.flags = e.flags;
@@ -316,7 +316,8 @@
currentIOOptions(new ConfigOptionVector()),
ioType(xstrdup(anIOType)),
cur_size(0),
- n_disk_objects(0)
+ n_disk_objects(0),
+ rebuilding_(false)
{
/* modulename is only set to disk modules that are built, by configure,
* so the Find call should never return NULL here.
@@ -723,6 +724,15 @@
void
Fs::Ufs::UFSSwapDir::openLog()
{
+ assert(NumberOfUFSDirs || !UFSDirToGlobalDirMapping);
+ ++NumberOfUFSDirs;
+ assert(NumberOfUFSDirs <= Config.cacheSwap.n_configured);
+
+ if (rebuilding_) { // we did not close the temporary log used for rebuilding
+ assert(swaplog_fd >= 0);
+ return;
+ }
+
char *logPath;
logPath = logFile();
swaplog_fd = file_open(logPath, O_WRONLY | O_CREAT | O_BINARY);
@@ -733,13 +743,6 @@
}
debugs(50, 3, HERE << "Cache Dir #" << index << " log opened on FD " << swaplog_fd);
-
- if (0 == NumberOfUFSDirs)
- assert(NULL == UFSDirToGlobalDirMapping);
-
- ++NumberOfUFSDirs;
-
- assert(NumberOfUFSDirs <= Config.cacheSwap.n_configured);
}
void
@@ -748,18 +751,19 @@
if (swaplog_fd < 0) /* not open */
return;
+ --NumberOfUFSDirs;
+ assert(NumberOfUFSDirs >= 0);
+ if (!NumberOfUFSDirs)
+ safe_free(UFSDirToGlobalDirMapping);
+
+ if (rebuilding_) // we cannot close the temporary log used for rebuilding
+ return;
+
file_close(swaplog_fd);
debugs(47, 3, "Cache Dir #" << index << " log closed on FD " << swaplog_fd);
swaplog_fd = -1;
-
- --NumberOfUFSDirs;
-
- assert(NumberOfUFSDirs >= 0);
-
- if (0 == NumberOfUFSDirs)
- safe_free(UFSDirToGlobalDirMapping);
}
bool
@@ -801,7 +805,7 @@
e->lastref = lastref;
e->timestamp = timestamp;
e->expires = expires;
- e->lastmod = lastmod;
+ e->lastModified(lastmod);
e->refcount = refcount;
e->flags = newFlags;
EBIT_CLR(e->flags, RELEASE_REQUEST);
@@ -839,6 +843,9 @@
void
Fs::Ufs::UFSSwapDir::closeTmpSwapLog()
{
+ assert(rebuilding_);
+ rebuilding_ = false;
+
char *swaplog_path = xstrdup(logFile(NULL)); // where the swaplog should be
char *tmp_path = xstrdup(logFile(".new")); // the temporary file we have generated
int fd;
@@ -864,6 +871,8 @@
FILE *
Fs::Ufs::UFSSwapDir::openTmpSwapLog(int *clean_flag, int *zero_flag)
{
+ assert(!rebuilding_);
+
char *swaplog_path = xstrdup(logFile(NULL));
char *clean_path = xstrdup(logFile(".last-clean"));
char *new_path = xstrdup(logFile(".new"));
@@ -897,6 +906,7 @@
}
swaplog_fd = fd;
+ rebuilding_ = true;
{
const StoreSwapLogHeader header;
@@ -1053,18 +1063,17 @@
cleanLog = NULL;
}
-void
-Fs::Ufs::UFSSwapDir::CleanEvent(void *unused)
+/// safely cleans a few unused files if possible
+int
+Fs::Ufs::UFSSwapDir::HandleCleanEvent()
{
static int swap_index = 0;
int i;
int j = 0;
int n = 0;
- /*
- * Assert that there are UFS cache_dirs configured, otherwise
- * we should never be called.
- */
- assert(NumberOfUFSDirs);
+
+ if (!NumberOfUFSDirs)
+ return 0; // probably in the middle of reconfiguration
if (NULL == UFSDirToGlobalDirMapping) {
SwapDir *sd;
@@ -1106,6 +1115,13 @@
++swap_index;
}
+ return n;
+}
+
+void
+Fs::Ufs::UFSSwapDir::CleanEvent(void *)
+{
+ const int n = HandleCleanEvent();
eventAdd("storeDirClean", CleanEvent, NULL,
15.0 * exp(-0.25 * n), 1);
}
@@ -1283,13 +1299,18 @@
void
Fs::Ufs::UFSSwapDir::logEntry(const StoreEntry & e, int op) const
{
+ if (swaplog_fd < 0) {
+ debugs(36, 5, "cannot log " << e << " in the middle of reconfiguration");
+ return;
+ }
+
StoreSwapLogData *s = new StoreSwapLogData;
s->op = (char) op;
s->swap_filen = e.swap_filen;
s->timestamp = e.timestamp;
s->lastref = e.lastref;
s->expires = e.expires;
- s->lastmod = e.lastmod;
+ s->lastmod = e.lastModified();
s->swap_file_sz = e.swap_file_sz;
s->refcount = e.refcount;
s->flags = e.flags;
diff -u -r -N squid-3.5.21/src/fs/ufs/UFSSwapDir.h squid-3.5.22/src/fs/ufs/UFSSwapDir.h
--- squid-3.5.21/src/fs/ufs/UFSSwapDir.h 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/fs/ufs/UFSSwapDir.h 2016-10-10 08:58:01.000000000 +1300
@@ -90,6 +90,7 @@
virtual void swappedOut(const StoreEntry &e);
virtual uint64_t currentSize() const { return cur_size; }
virtual uint64_t currentCount() const { return n_disk_objects; }
+ virtual bool smpAware() const { return false; }
void unlinkFile(sfileno f);
// move down when unlink is a virtual method
@@ -145,6 +146,7 @@
bool pathIsDirectory(const char *path)const;
int swaplog_fd;
static EVH CleanEvent;
+ static int HandleCleanEvent();
/** Verify that the the CacheDir exists
*
* If this returns < 0, then Squid exits, complains about swap
@@ -164,6 +166,7 @@
char const *ioType;
uint64_t cur_size; ///< currently used space in the storage area
uint64_t n_disk_objects; ///< total number of objects stored
+ bool rebuilding_; ///< whether RebuildState is writing the new swap.state
};
} //namespace Ufs
diff -u -r -N squid-3.5.21/src/htcp.cc squid-3.5.22/src/htcp.cc
--- squid-3.5.21/src/htcp.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/htcp.cc 2016-10-10 08:58:01.000000000 +1300
@@ -886,8 +886,8 @@
if (e && e->expires > -1)
hdr.putTime(HDR_EXPIRES, e->expires);
- if (e && e->lastmod > -1)
- hdr.putTime(HDR_LAST_MODIFIED, e->lastmod);
+ if (e && e->lastModified() > -1)
+ hdr.putTime(HDR_LAST_MODIFIED, e->lastModified());
hdr.packInto(&p);
diff -u -r -N squid-3.5.21/src/http.cc squid-3.5.22/src/http.cc
--- squid-3.5.21/src/http.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/http.cc 2016-10-10 08:58:01.000000000 +1300
@@ -84,7 +84,8 @@
HttpStateData::HttpStateData(FwdState *theFwdState) : AsyncJob("HttpStateData"), Client(theFwdState),
lastChunk(0), header_bytes_read(0), reply_bytes_read(0),
- body_bytes_truncated(0), httpChunkDecoder(NULL)
+ body_bytes_truncated(0), httpChunkDecoder(NULL),
+ sawDateGoBack(false)
{
debugs(11,5,HERE << "HttpStateData " << this << " created");
ignoreCacheControl = false;
@@ -169,6 +170,14 @@
mustStop("HttpStateData::httpTimeout");
}
+static StoreEntry *
+findPreviouslyCachedEntry(StoreEntry *newEntry) {
+ assert(newEntry->mem_obj);
+ return newEntry->mem_obj->request ?
+ storeGetPublicByRequest(newEntry->mem_obj->request) :
+ storeGetPublic(newEntry->mem_obj->storeId(), newEntry->mem_obj->method);
+}
+
/// Remove an existing public store entry if the incoming response (to be
/// stored in a currently private entry) is going to invalidate it.
static void
@@ -176,7 +185,6 @@
{
int remove = 0;
int forbidden = 0;
- StoreEntry *pe;
// If the incoming response already goes into a public entry, then there is
// nothing to remove. This protects ready-for-collapsing entries as well.
@@ -235,12 +243,7 @@
if (!remove && !forbidden)
return;
- assert(e->mem_obj);
-
- if (e->mem_obj->request)
- pe = storeGetPublicByRequest(e->mem_obj->request);
- else
- pe = storeGetPublic(e->mem_obj->storeId(), e->mem_obj->method);
+ StoreEntry *pe = findPreviouslyCachedEntry(e);
if (pe != NULL) {
assert(e != pe);
@@ -331,6 +334,13 @@
return 0;
}
+ // RFC 7234 section 4: a cache MUST use the most recent response
+ // (as determined by the Date header field)
+ if (sawDateGoBack) {
+ debugs(22, 3, "NO because " << *entry << " has an older date header.");
+ return 0;
+ }
+
// Check for Surrogate/1.0 protocol conditions
// NP: reverse-proxy traffic our parent server has instructed us never to cache
if (surrogateNoStore) {
@@ -886,7 +896,10 @@
/* Check if object is cacheable or not based on reply code */
debugs(11, 3, "HTTP CODE: " << rep->sline.status());
- if (neighbors_do_private_keys)
+ if (const StoreEntry *oldEntry = findPreviouslyCachedEntry(entry))
+ sawDateGoBack = rep->olderThan(oldEntry->getReply());
+
+ if (neighbors_do_private_keys && !sawDateGoBack)
httpMaybeRemovePublic(entry, rep->sline.status());
bool varyFailure = false;
diff -u -r -N squid-3.5.21/src/http.h squid-3.5.22/src/http.h
--- squid-3.5.21/src/http.h 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/http.h 2016-10-10 08:58:01.000000000 +1300
@@ -112,6 +112,9 @@
bool peerSupportsConnectionPinning() const;
ChunkedCodingParser *httpChunkDecoder;
+ /// Whether we received a Date header older than that of a matching
+ /// cached response.
+ bool sawDateGoBack;
private:
CBDATA_CLASS2(HttpStateData);
};
diff -u -r -N squid-3.5.21/src/HttpHeader.cc squid-3.5.22/src/HttpHeader.cc
--- squid-3.5.21/src/HttpHeader.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/HttpHeader.cc 2016-10-10 08:58:01.000000000 +1300
@@ -450,7 +450,7 @@
HttpHeader::HttpHeader(const HttpHeader &other): owner(other.owner), len(other.len), conflictingContentLength_(false)
{
httpHeaderMaskInit(&mask, 0);
- update(&other, NULL); // will update the mask as well
+ update(&other); // will update the mask as well
}
HttpHeader::~HttpHeader()
@@ -465,7 +465,7 @@
// we do not really care, but the caller probably does
assert(owner == other.owner);
clean();
- update(&other, NULL); // will update the mask as well
+ update(&other); // will update the mask as well
len = other.len;
conflictingContentLength_ = other.conflictingContentLength_;
}
@@ -535,26 +535,71 @@
}
}
+/// check whether the fresh header has any new/changed updatable fields
+bool
+HttpHeader::needUpdate(HttpHeader const *fresh) const
+{
+ for (unsigned int i = 0; i < fresh->entries.size(); ++i) {
+ const HttpHeaderEntry *e = fresh->entries[i];
+ if (!e || skipUpdateHeader(e->id))
+ continue;
+ String value;
+ const char *name = e->name.termedBuf();
+ if (!getByNameIfPresent(name, value) ||
+ (value != fresh->getByName(name)))
+ return true;
+ }
+ return false;
+}
+
/* use fresh entries to replace old ones */
void
httpHeaderUpdate(HttpHeader * old, const HttpHeader * fresh, const HttpHeaderMask * denied_mask)
{
assert (old);
- old->update (fresh, denied_mask);
+ old->update(fresh);
}
void
-HttpHeader::update (HttpHeader const *fresh, HttpHeaderMask const *denied_mask)
+HttpHeader::updateWarnings()
{
- const HttpHeaderEntry *e;
+ int count = 0;
HttpHeaderPos pos = HttpHeaderInitPos;
+
+ // RFC 7234, section 4.3.4: delete 1xx warnings and retain 2xx warnings
+ while (HttpHeaderEntry *e = getEntry(&pos)) {
+ if (e->id == HDR_WARNING && (e->getInt()/100 == 1) )
+ delAt(pos, count);
+ }
+}
+
+bool
+HttpHeader::skipUpdateHeader(const http_hdr_type id) const
+{
+ // RFC 7234, section 4.3.4: use fields other from Warning for update
+ return id == HDR_WARNING;
+}
+
+bool
+HttpHeader::update(HttpHeader const *fresh)
+{
assert(fresh);
assert(this != fresh);
+ // Optimization: Finding whether a header field changed is expensive
+ // and probably not worth it except for collapsed revalidation needs.
+ if (Config.onoff.collapsed_forwarding && !needUpdate(fresh))
+ return false;
+
+ updateWarnings();
+
+ const HttpHeaderEntry *e;
+ HttpHeaderPos pos = HttpHeaderInitPos;
+
while ((e = fresh->getEntry(&pos))) {
/* deny bad guys (ok to check for HDR_OTHER) here */
- if (denied_mask && CBIT_TEST(*denied_mask, e->id))
+ if (skipUpdateHeader(e->id))
continue;
if (e->id != HDR_OTHER)
@@ -567,13 +612,14 @@
while ((e = fresh->getEntry(&pos))) {
/* deny bad guys (ok to check for HDR_OTHER) here */
- if (denied_mask && CBIT_TEST(*denied_mask, e->id))
+ if (skipUpdateHeader(e->id))
continue;
debugs(55, 7, "Updating header '" << HeadersAttrs[e->id].name << "' in cached entry");
addEntry(e->clone());
}
+ return true;
}
/* just handy in parsing: resets and returns false */
@@ -1720,7 +1766,6 @@
HttpHeaderEntry::getInt() const
{
assert_eid (id);
- assert (Headers[id].type == ftInt);
int val = -1;
int ok = httpHeaderParseInt(value.termedBuf(), &val);
httpHeaderNoteParsedEntry(id, value, !ok);
@@ -1734,7 +1779,6 @@
HttpHeaderEntry::getInt64() const
{
assert_eid (id);
- assert (Headers[id].type == ftInt64);
int64_t val = -1;
int ok = httpHeaderParseOffset(value.termedBuf(), &val);
httpHeaderNoteParsedEntry(id, value, !ok);
diff -u -r -N squid-3.5.21/src/HttpHeader.h squid-3.5.22/src/HttpHeader.h
--- squid-3.5.21/src/HttpHeader.h 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/HttpHeader.h 2016-10-10 08:58:01.000000000 +1300
@@ -217,7 +217,7 @@
/* Interface functions */
void clean();
void append(const HttpHeader * src);
- void update (HttpHeader const *fresh, HttpHeaderMask const *denied_mask);
+ bool update(HttpHeader const *fresh);
void compact();
int reset();
int parse(const char *header_start, const char *header_end);
@@ -278,6 +278,9 @@
protected:
/** \deprecated Public access replaced by removeHopByHopEntries() */
void removeConnectionHeaderEntries();
+ bool needUpdate(const HttpHeader *fresh) const;
+ bool skipUpdateHeader(const http_hdr_type id) const;
+ void updateWarnings();
private:
HttpHeaderEntry *findLastEntry(http_hdr_type id) const;
diff -u -r -N squid-3.5.21/src/HttpReply.cc squid-3.5.22/src/HttpReply.cc
--- squid-3.5.21/src/HttpReply.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/HttpReply.cc 2016-10-10 08:58:01.000000000 +1300
@@ -24,40 +24,6 @@
#include "Store.h"
#include "StrList.h"
-/* local constants */
-
-/* If we receive a 304 from the origin during a cache revalidation, we must
- * update the headers of the existing entry. Specifically, we need to update all
- * end-to-end headers and not any hop-by-hop headers (rfc2616 13.5.3).
- *
- * This is not the whole story though: since it is possible for a faulty/malicious
- * origin server to set headers it should not in a 304, we must explicitly ignore
- * these too. Specifically all entity-headers except those permitted in a 304
- * (rfc2616 10.3.5) must be ignored.
- *
- * The list of headers we don't update is made up of:
- * all hop-by-hop headers
- * all entity-headers except Expires and Content-Location
- */
-static HttpHeaderMask Denied304HeadersMask;
-static http_hdr_type Denied304HeadersArr[] = {
- // hop-by-hop headers
- HDR_CONNECTION, HDR_KEEP_ALIVE, HDR_PROXY_AUTHENTICATE, HDR_PROXY_AUTHORIZATION,
- 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
-};
-
-/* module initialization */
-void
-httpReplyInitModule(void)
-{
- assert(Http::scNone == 0); // HttpReply::parse() interface assumes that
- httpHeaderMaskInit(&Denied304HeadersMask, 0);
- httpHeaderCalcMask(&Denied304HeadersMask, Denied304HeadersArr, countof(Denied304HeadersArr));
-}
-
HttpReply::HttpReply() : HttpMsg(hoReply), date (0), last_modified (0),
expires (0), surrogate_control (NULL), content_range (NULL), keep_alive (0),
protoPrefix("HTTP/"), bodySizeMax(-2)
@@ -271,20 +237,23 @@
return 1;
}
-void
+bool
HttpReply::updateOnNotModified(HttpReply const * freshRep)
{
assert(freshRep);
+ /* update raw headers */
+ if (!header.update(&freshRep->header))
+ return false;
+
/* clean cache */
hdrCacheClean();
- /* update raw headers */
- header.update(&freshRep->header,
- (const HttpHeaderMask *) &Denied304HeadersMask);
header.compact();
/* init cache */
hdrCacheInit();
+
+ return true;
}
/* internal routines */
@@ -659,3 +628,11 @@
return newValue;
}
+bool
+HttpReply::olderThan(const HttpReply *them) const
+{
+ if (!them || !them->date || !date)
+ return false;
+ return date < them->date;
+}
+
diff -u -r -N squid-3.5.21/src/HttpReply.h squid-3.5.22/src/HttpReply.h
--- squid-3.5.21/src/HttpReply.h 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/HttpReply.h 2016-10-10 08:58:01.000000000 +1300
@@ -72,7 +72,7 @@
virtual bool inheritProperties(const HttpMsg *aMsg);
- void updateOnNotModified(HttpReply const *other);
+ bool updateOnNotModified(HttpReply const *other);
/** set commonly used info with one call */
void setHeaders(Http::StatusCode status,
@@ -112,6 +112,10 @@
virtual void hdrCacheInit();
+ /// whether our Date header value is smaller than theirs
+ /// \returns false if any information is missing
+ bool olderThan(const HttpReply *them) const;
+
private:
/** initialize */
void init();
diff -u -r -N squid-3.5.21/src/ip/Intercept.cc squid-3.5.22/src/ip/Intercept.cc
--- squid-3.5.21/src/ip/Intercept.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/ip/Intercept.cc 2016-10-10 08:58:01.000000000 +1300
@@ -207,16 +207,22 @@
debugs(89, warningLevel, "IPF (IPFilter v4) NAT does not support IPv6. Please upgrade to IPFilter v5.1");
warningLevel = (warningLevel + 1) % 10;
return false;
+ }
+ newConn->local.getInAddr(natLookup.nl_inip);
+ newConn->remote.getInAddr(natLookup.nl_outip);
#else
natLookup.nl_v = 6;
- } else {
+ newConn->local.getInAddr(natLookup.nl_inipaddr.in6);
+ newConn->remote.getInAddr(natLookup.nl_outipaddr.in6);
+ }
+ else {
natLookup.nl_v = 4;
-#endif
+ newConn->local.getInAddr(natLookup.nl_inipaddr.in4);
+ newConn->remote.getInAddr(natLookup.nl_outipaddr.in4);
}
+#endif
natLookup.nl_inport = htons(newConn->local.port());
- newConn->local.getInAddr(natLookup.nl_inip);
natLookup.nl_outport = htons(newConn->remote.port());
- newConn->remote.getInAddr(natLookup.nl_outip);
// ... and the TCP flag
natLookup.nl_flags = IPN_TCP;
@@ -281,7 +287,14 @@
debugs(89, 9, HERE << "address: " << newConn);
return false;
} else {
+#if IPFILTER_VERSION < 5000003
newConn->local = natLookup.nl_realip;
+#else
+ if (newConn->remote.isIPv6())
+ newConn->local = natLookup.nl_realipaddr.in6;
+ else
+ newConn->local = natLookup.nl_realipaddr.in4;
+#endif
newConn->local.port(ntohs(natLookup.nl_realport));
debugs(89, 5, HERE << "address NAT: " << newConn);
return true;
diff -u -r -N squid-3.5.21/src/ipc/StoreMap.cc squid-3.5.22/src/ipc/StoreMap.cc
--- squid-3.5.21/src/ipc/StoreMap.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/ipc/StoreMap.cc 2016-10-10 08:58:01.000000000 +1300
@@ -491,7 +491,7 @@
basics.timestamp = from.timestamp;
basics.lastref = from.lastref;
basics.expires = from.expires;
- basics.lastmod = from.lastmod;
+ basics.lastmod = from.lastModified();
basics.swap_file_sz = from.swap_file_sz;
basics.refcount = from.refcount;
basics.flags = from.flags;
diff -u -r -N squid-3.5.21/src/LogTags.h squid-3.5.22/src/LogTags.h
--- squid-3.5.21/src/LogTags.h 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/LogTags.h 2016-10-10 08:58:01.000000000 +1300
@@ -25,6 +25,7 @@
LOG_TCP_REFRESH_FAIL_OLD, // refresh from origin failed, stale reply sent
LOG_TCP_REFRESH_FAIL_ERR, // refresh from origin failed, error forwarded
LOG_TCP_REFRESH_MODIFIED, // refresh from origin replaced existing entry
+ LOG_TCP_REFRESH_IGNORED, // refresh from origin ignored, stale entry sent
LOG_TCP_CLIENT_REFRESH_MISS,
LOG_TCP_IMS_HIT,
LOG_TCP_SWAPFAIL_MISS,
diff -u -r -N squid-3.5.21/src/main.cc squid-3.5.22/src/main.cc
--- squid-3.5.21/src/main.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/main.cc 2016-10-10 08:58:01.000000000 +1300
@@ -1069,8 +1069,6 @@
httpHeaderInitModule(); /* must go before any header processing (e.g. the one in errorInitialize) */
- httpReplyInitModule(); /* must go before accepting replies */
-
errorInitialize();
accessLogInit();
diff -u -r -N squid-3.5.21/src/MemBlob.h squid-3.5.22/src/MemBlob.h
--- squid-3.5.21/src/MemBlob.h 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/MemBlob.h 2016-10-10 08:58:01.000000000 +1300
@@ -72,7 +72,7 @@
*/
bool canAppend(const size_type off, const size_type n) const {
// TODO: ignore offset (and adjust size) when the blob is not shared?
- return isAppendOffset(off) && willFit(n);
+ return (isAppendOffset(off) && willFit(n)) || !n;
}
/** adjusts internal object state as if exactly n bytes were append()ed
diff -u -r -N squid-3.5.21/src/MemStore.cc squid-3.5.22/src/MemStore.cc
--- squid-3.5.21/src/MemStore.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/MemStore.cc 2016-10-10 08:58:01.000000000 +1300
@@ -281,7 +281,7 @@
e.lastref = basics.lastref;
e.timestamp = basics.timestamp;
e.expires = basics.expires;
- e.lastmod = basics.lastmod;
+ e.lastModified(basics.lastmod);
e.refcount = basics.refcount;
e.flags = basics.flags;
diff -u -r -N squid-3.5.21/src/MemStore.h squid-3.5.22/src/MemStore.h
--- squid-3.5.21/src/MemStore.h 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/MemStore.h 2016-10-10 08:58:01.000000000 +1300
@@ -63,6 +63,7 @@
virtual void maintain();
virtual bool anchorCollapsed(StoreEntry &collapsed, bool &inSync);
virtual bool updateCollapsed(StoreEntry &collapsed);
+ virtual bool smpAware() const { return true; }
static int64_t EntryLimit();
diff -u -r -N squid-3.5.21/src/peer_digest.cc squid-3.5.22/src/peer_digest.cc
--- squid-3.5.21/src/peer_digest.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/peer_digest.cc 2016-10-10 08:58:01.000000000 +1300
@@ -359,7 +359,7 @@
/* set lastmod to trigger IMS request if possible */
if (old_e)
- e->lastmod = old_e->lastmod;
+ e->lastModified(old_e->lastModified());
/* push towards peer cache */
debugs(72, 3, "peerDigestRequest: forwarding to fwdStart...");
@@ -942,8 +942,8 @@
debugs(72, 3, "peerDigestFetchFinish: expires: " <<
(long int) fetch->expires << " (" << std::showpos <<
(int) (fetch->expires - squid_curtime) << "), lmt: " <<
- std::noshowpos << (long int) fetch->entry->lastmod << " (" <<
- std::showpos << (int) (fetch->entry->lastmod - squid_curtime) <<
+ std::noshowpos << (long int) fetch->entry->lastModified() << " (" <<
+ std::showpos << (int) (fetch->entry->lastModified() - squid_curtime) <<
")");
}
diff -u -r -N squid-3.5.21/src/redirect.cc squid-3.5.22/src/redirect.cc
--- squid-3.5.21/src/redirect.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/redirect.cc 2016-10-10 08:58:01.000000000 +1300
@@ -369,11 +369,13 @@
}
if (Config.redirector_extras) {
+ delete redirectorExtrasFmt;
redirectorExtrasFmt = new ::Format::Format("url_rewrite_extras");
(void)redirectorExtrasFmt->parse(Config.redirector_extras);
}
if (Config.storeId_extras) {
+ delete storeIdExtrasFmt;
storeIdExtrasFmt = new ::Format::Format("store_id_extras");
(void)storeIdExtrasFmt->parse(Config.storeId_extras);
}
@@ -388,9 +390,6 @@
* When and if needed for more helpers a separated shutdown
* method will be added for each of them.
*/
- if (!storeIds && !redirectors)
- return;
-
if (redirectors)
helperShutdown(redirectors);
diff -u -r -N squid-3.5.21/src/refresh.cc squid-3.5.22/src/refresh.cc
--- squid-3.5.21/src/refresh.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/refresh.cc 2016-10-10 08:58:01.000000000 +1300
@@ -186,13 +186,8 @@
}
// 3. If there is a Last-Modified header, try the last-modified factor algorithm.
- if (entry->lastmod > -1 && entry->timestamp > entry->lastmod) {
-
- /* lastmod_delta is the difference between the last-modified date of the response
- * and the time we cached it. It's how "old" the response was when we got it.
- */
- time_t lastmod_delta = entry->timestamp - entry->lastmod;
-
+ const time_t lastmod_delta = entry->timestamp - entry->lastModified();
+ if (lastmod_delta > 0) {
/* stale_age is the age of the response when it became/becomes stale according to
* the last-modified factor algorithm. It's how long we can consider the response
* fresh from the time we cached it.
@@ -553,8 +548,8 @@
/* Does not need refresh. This is certainly cachable */
return true;
- if (entry->lastmod < 0)
- /* Last modified is needed to do a refresh */
+ if (entry->lastModified() < 0)
+ /* We should know entry's modification time to do a refresh */
return false;
if (entry->mem_obj == NULL)
diff -u -r -N squid-3.5.21/src/ssl/PeerConnector.cc squid-3.5.22/src/ssl/PeerConnector.cc
--- squid-3.5.21/src/ssl/PeerConnector.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/ssl/PeerConnector.cc 2016-10-10 08:58:01.000000000 +1300
@@ -771,7 +771,7 @@
}
if (serverConn != NULL)
buf.Printf(" FD %d", serverConn->fd);
- buf.Printf(" %s%u]", id.Prefix, id.value);
+ buf.Printf(" %s%u]", id.prefix(), id.value);
buf.terminate();
return buf.content();
diff -u -r -N squid-3.5.21/src/ssl/support.cc squid-3.5.22/src/ssl/support.cc
--- squid-3.5.21/src/ssl/support.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/ssl/support.cc 2016-10-10 08:58:01.000000000 +1300
@@ -1350,7 +1350,6 @@
ssl_read_method(int fd, char *buf, int len)
{
SSL *ssl = fd_table[fd].ssl;
- int i;
#if DONT_DO_THIS
@@ -1361,7 +1360,10 @@
#endif
- i = SSL_read(ssl, buf, len);
+ int i = SSL_read(ssl, buf, len);
+ if (i > 0) {
+ (void)VALGRIND_MAKE_MEM_DEFINED(buf, i);
+ }
if (i > 0 && SSL_pending(ssl) > 0) {
debugs(83, 2, "SSL FD " << fd << " is pending");
diff -u -r -N squid-3.5.21/src/stat.cc squid-3.5.22/src/stat.cc
--- squid-3.5.21/src/stat.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/stat.cc 2016-10-10 08:58:01.000000000 +1300
@@ -77,7 +77,6 @@
/* LOCALS */
static const char *describeStatuses(const StoreEntry *);
-static const char *describeTimestamps(const StoreEntry *);
static void statAvgTick(void *notused);
static void statAvgDump(StoreEntry *, int minutes, int hours);
#if STAT_GRAPHS
@@ -328,18 +327,6 @@
return buf;
}
-static const char *
-describeTimestamps(const StoreEntry * entry)
-{
- LOCAL_ARRAY(char, buf, 256);
- snprintf(buf, 256, "LV:%-9d LU:%-9d LM:%-9d EX:%-9d",
- (int) entry->timestamp,
- (int) entry->lastref,
- (int) entry->lastmod,
- (int) entry->expires);
- return buf;
-}
-
static void
statStoreEntry(MemBuf * mb, StoreEntry * e)
{
@@ -347,7 +334,7 @@
mb->Printf("KEY %s\n", e->getMD5Text());
mb->Printf("\t%s\n", describeStatuses(e));
mb->Printf("\t%s\n", storeEntryFlags(e));
- mb->Printf("\t%s\n", describeTimestamps(e));
+ mb->Printf("\t%s\n", e->describeTimestamps());
mb->Printf("\t%d locks, %d clients, %d refs\n",
(int) e->locks(),
storePendingNClients(e),
diff -u -r -N squid-3.5.21/src/store.cc squid-3.5.22/src/store.cc
--- squid-3.5.21/src/store.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/store.cc 2016-10-10 08:58:01.000000000 +1300
@@ -162,12 +162,12 @@
}
void
-StoreEntry::makePublic()
+StoreEntry::makePublic(const KeyScope scope)
{
/* This object can be cached for a long time */
if (!EBIT_TEST(flags, RELEASE_REQUEST))
- setPublicKey();
+ setPublicKey(scope);
}
void
@@ -355,7 +355,7 @@
timestamp(-1),
lastref(-1),
expires(-1),
- lastmod(-1),
+ lastModified_(-1),
swap_file_sz(0),
refcount(0),
flags(0),
@@ -585,19 +585,19 @@
}
StoreEntry *
-storeGetPublicByRequestMethod(HttpRequest * req, const HttpRequestMethod& method)
+storeGetPublicByRequestMethod(HttpRequest * req, const HttpRequestMethod& method, const KeyScope keyScope)
{
- return Store::Root().get(storeKeyPublicByRequestMethod(req, method));
+ return Store::Root().get(storeKeyPublicByRequestMethod(req, method, keyScope));
}
StoreEntry *
-storeGetPublicByRequest(HttpRequest * req)
+storeGetPublicByRequest(HttpRequest * req, const KeyScope keyScope)
{
- StoreEntry *e = storeGetPublicByRequestMethod(req, req->method);
+ StoreEntry *e = storeGetPublicByRequestMethod(req, req->method, keyScope);
if (e == NULL && req->method == Http::METHOD_HEAD)
/* We can generate a HEAD reply from a cached GET object */
- e = storeGetPublicByRequestMethod(req, Http::METHOD_GET);
+ e = storeGetPublicByRequestMethod(req, Http::METHOD_GET, keyScope);
return e;
}
@@ -653,10 +653,8 @@
}
void
-StoreEntry::setPublicKey()
+StoreEntry::setPublicKey(const KeyScope scope)
{
- const cache_key *newkey;
-
if (key && !EBIT_TEST(flags, KEY_PRIVATE))
return; /* is already public */
@@ -680,80 +678,35 @@
assert(!EBIT_TEST(flags, RELEASE_REQUEST));
- if (mem_obj->request) {
- HttpRequest *request = mem_obj->request;
-
- if (mem_obj->vary_headers.isEmpty()) {
- /* First handle the case where the object no longer varies */
- request->vary_headers.clear();
- } else {
- if (!request->vary_headers.isEmpty() && request->vary_headers.cmp(mem_obj->vary_headers) != 0) {
- /* Oops.. the variance has changed. Kill the base object
- * to record the new variance key
- */
- request->vary_headers.clear(); /* free old "bad" variance key */
- if (StoreEntry *pe = storeGetPublic(mem_obj->storeId(), mem_obj->method))
- pe->release();
- }
-
- /* Make sure the request knows the variance status */
- if (request->vary_headers.isEmpty())
- request->vary_headers = httpMakeVaryMark(request, mem_obj->getReply());
- }
-
- // TODO: storeGetPublic() calls below may create unlocked entries.
- // We should add/use storeHas() API or lock/unlock those entries.
- if (!mem_obj->vary_headers.isEmpty() && !storeGetPublic(mem_obj->storeId(), mem_obj->method)) {
- /* Create "vary" base object */
- String vary;
- StoreEntry *pe = storeCreateEntry(mem_obj->storeId(), mem_obj->logUri(), request->flags, request->method);
- /* We are allowed to do this typecast */
- HttpReply *rep = new HttpReply;
- rep->setHeaders(Http::scOkay, "Internal marker object", "x-squid-internal/vary", -1, -1, squid_curtime + 100000);
- vary = mem_obj->getReply()->header.getList(HDR_VARY);
-
- if (vary.size()) {
- /* Again, we own this structure layout */
- rep->header.putStr(HDR_VARY, vary.termedBuf());
- vary.clean();
- }
-
-#if X_ACCELERATOR_VARY
- vary = mem_obj->getReply()->header.getList(HDR_X_ACCELERATOR_VARY);
-
- if (vary.size() > 0) {
- /* Again, we own this structure layout */
- rep->header.putStr(HDR_X_ACCELERATOR_VARY, vary.termedBuf());
- vary.clean();
- }
-
-#endif
- pe->replaceHttpReply(rep, false); // no write until key is public
-
- pe->timestampsSet();
-
- pe->makePublic();
+ adjustVary();
+ forcePublicKey(calcPublicKey(scope));
+}
- pe->startWriting(); // after makePublic()
+void
+StoreEntry::clearPublicKeyScope()
+{
+ if (!key || EBIT_TEST(flags, KEY_PRIVATE))
+ return; // probably the old public key was deleted or made private
- pe->complete();
+ // TODO: adjustVary() when collapsed revalidation supports that
- pe->unlock("StoreEntry::setPublicKey+Vary");
- }
+ const cache_key *newKey = calcPublicKey(ksDefault);
+ if (!storeKeyHashCmp(key, newKey))
+ return; // probably another collapsed revalidation beat us to this change
- newkey = storeKeyPublicByRequest(mem_obj->request);
- } else
- newkey = storeKeyPublic(mem_obj->storeId(), mem_obj->method);
+ forcePublicKey(newKey);
+}
+/// Unconditionally sets public key for this store entry.
+/// Releases the old entry with the same public key (if any).
+void
+StoreEntry::forcePublicKey(const cache_key *newkey)
+{
if (StoreEntry *e2 = (StoreEntry *)hash_lookup(store_table, newkey)) {
+ assert(e2 != this);
debugs(20, 3, "Making old " << *e2 << " private.");
e2->setPrivateKey();
e2->release();
-
- if (mem_obj->request)
- newkey = storeKeyPublicByRequest(mem_obj->request);
- else
- newkey = storeKeyPublic(mem_obj->storeId(), mem_obj->method);
}
if (key)
@@ -767,6 +720,84 @@
storeDirSwapLog(this, SWAP_LOG_ADD);
}
+/// Calculates correct public key for feeding forcePublicKey().
+/// Assumes adjustVary() has been called for this entry already.
+const cache_key *StoreEntry::calcPublicKey(const KeyScope keyScope) {
+ assert(mem_obj);
+ return mem_obj->request ? storeKeyPublicByRequest(mem_obj->request, keyScope) :
+ storeKeyPublic(mem_obj->storeId(), mem_obj->method, keyScope);
+}
+
+/// Updates mem_obj->request->vary_headers to reflect the current Vary.
+/// The vary_headers field is used to calculate the Vary marker key.
+/// Releases the old Vary marker with an outdated key (if any).
+void StoreEntry::adjustVary() {
+ assert(mem_obj);
+
+ if (!mem_obj->request)
+ return;
+
+ HttpRequest *request = mem_obj->request;
+
+ if (mem_obj->vary_headers.isEmpty()) {
+ /* First handle the case where the object no longer varies */
+ request->vary_headers.clear();
+ } else {
+ if (!request->vary_headers.isEmpty() && request->vary_headers.cmp(mem_obj->vary_headers) != 0) {
+ /* Oops.. the variance has changed. Kill the base object
+ * to record the new variance key
+ */
+ request->vary_headers.clear(); /* free old "bad" variance key */
+ if (StoreEntry *pe = storeGetPublic(mem_obj->storeId(), mem_obj->method))
+ pe->release();
+ }
+
+ /* Make sure the request knows the variance status */
+ if (request->vary_headers.isEmpty())
+ request->vary_headers = httpMakeVaryMark(request, mem_obj->getReply());
+ }
+
+ // TODO: storeGetPublic() calls below may create unlocked entries.
+ // We should add/use storeHas() API or lock/unlock those entries.
+ if (!mem_obj->vary_headers.isEmpty() && !storeGetPublic(mem_obj->storeId(), mem_obj->method)) {
+ /* Create "vary" base object */
+ String vary;
+ StoreEntry *pe = storeCreateEntry(mem_obj->storeId(), mem_obj->logUri(), request->flags, request->method);
+ /* We are allowed to do this typecast */
+ HttpReply *rep = new HttpReply;
+ rep->setHeaders(Http::scOkay, "Internal marker object", "x-squid-internal/vary", -1, -1, squid_curtime + 100000);
+ vary = mem_obj->getReply()->header.getList(HDR_VARY);
+
+ if (vary.size()) {
+ /* Again, we own this structure layout */
+ rep->header.putStr(HDR_VARY, vary.termedBuf());
+ vary.clean();
+ }
+
+#if X_ACCELERATOR_VARY
+ vary = mem_obj->getReply()->header.getList(HDR_X_ACCELERATOR_VARY);
+
+ if (vary.size() > 0) {
+ /* Again, we own this structure layout */
+ rep->header.putStr(HDR_X_ACCELERATOR_VARY, vary.termedBuf());
+ vary.clean();
+ }
+
+#endif
+ pe->replaceHttpReply(rep, false); // no write until key is public
+
+ pe->timestampsSet();
+
+ pe->makePublic();
+
+ pe->startWriting(); // after makePublic()
+
+ pe->complete();
+
+ pe->unlock("StoreEntry::forcePublicKey+Vary");
+ }
+}
+
StoreEntry *
storeCreatePureEntry(const char *url, const char *log_url, const RequestFlags &flags, const HttpRequestMethod& method)
{
@@ -1549,7 +1580,7 @@
return 1;
}
-void
+bool
StoreEntry::timestampsSet()
{
const HttpReply *reply = getReply();
@@ -1587,14 +1618,27 @@
served_date -= (squid_curtime - request_sent);
}
+ time_t exp = 0;
if (reply->expires > 0 && reply->date > -1)
- expires = served_date + (reply->expires - reply->date);
+ exp = served_date + (reply->expires - reply->date);
else
- expires = reply->expires;
+ exp = reply->expires;
+
+ if (timestamp == served_date && expires == exp) {
+ // if the reply lacks LMT, then we now know that our effective
+ // LMT (i.e., timestamp) will stay the same, otherwise, old and
+ // new modification times must match
+ if (reply->last_modified < 0 || reply->last_modified == lastModified())
+ return false; // nothing has changed
+ }
+
+ expires = exp;
- lastmod = reply->last_modified;
+ lastModified_ = reply->last_modified;
timestamp = served_date;
+
+ return true;
}
void
@@ -1625,7 +1669,7 @@
debugs(20, l, "StoreEntry->timestamp: " << timestamp);
debugs(20, l, "StoreEntry->lastref: " << lastref);
debugs(20, l, "StoreEntry->expires: " << expires);
- debugs(20, l, "StoreEntry->lastmod: " << lastmod);
+ debugs(20, l, "StoreEntry->lastModified_: " << lastModified_);
debugs(20, l, "StoreEntry->swap_file_sz: " << swap_file_sz);
debugs(20, l, "StoreEntry->refcount: " << refcount);
debugs(20, l, "StoreEntry->flags: " << storeEntryFlags(this));
@@ -1756,7 +1800,7 @@
mem_obj->reset();
HttpReply *rep = (HttpReply *) getReply(); // bypass const
rep->reset();
- expires = lastmod = timestamp = -1;
+ expires = lastModified_ = timestamp = -1;
}
/*
@@ -1966,13 +2010,10 @@
}
bool
-StoreEntry::modifiedSince(HttpRequest * request) const
+StoreEntry::modifiedSince(const time_t ims, const int imslen) const
{
int object_length;
- time_t mod_time = lastmod;
-
- if (mod_time < 0)
- mod_time = timestamp;
+ const time_t mod_time = lastModified();
debugs(88, 3, "modifiedSince: '" << url() << "'");
@@ -1987,16 +2028,16 @@
if (object_length < 0)
object_length = contentLen();
- if (mod_time > request->ims) {
+ if (mod_time > ims) {
debugs(88, 3, "--> YES: entry newer than client");
return true;
- } else if (mod_time < request->ims) {
+ } else if (mod_time < ims) {
debugs(88, 3, "--> NO: entry older than client");
return false;
- } else if (request->imslen < 0) {
+ } else if (imslen < 0) {
debugs(88, 3, "--> NO: same LMT, no client length");
return false;
- } else if (request->imslen == object_length) {
+ } else if (imslen == object_length) {
debugs(88, 3, "--> NO: same LMT, same length");
return false;
} else {
@@ -2093,6 +2134,18 @@
return true;
}
+const char *
+StoreEntry::describeTimestamps() const
+{
+ LOCAL_ARRAY(char, buf, 256);
+ snprintf(buf, 256, "LV:%-9d LU:%-9d LM:%-9d EX:%-9d",
+ static_cast(timestamp),
+ static_cast(lastref),
+ static_cast(lastModified_),
+ static_cast(expires));
+ return buf;
+}
+
std::ostream &operator <<(std::ostream &os, const StoreEntry &e)
{
os << "e:";
diff -u -r -N squid-3.5.21/src/store_dir.cc squid-3.5.22/src/store_dir.cc
--- squid-3.5.21/src/store_dir.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/store_dir.cc 2016-10-10 08:58:01.000000000 +1300
@@ -77,7 +77,7 @@
debugs(47, DBG_IMPORTANT, "Using Least Load store dir selection");
}
- if (UsingSmp() && IamWorkerProcess() && Config.onoff.collapsed_forwarding) {
+ if (UsingSmp() && IamWorkerProcess() && Config.onoff.collapsed_forwarding && smpAware()) {
transients = new Transients;
transients->init();
}
@@ -916,7 +916,8 @@
StoreController::allowCollapsing(StoreEntry *e, const RequestFlags &reqFlags,
const HttpRequestMethod &reqMethod)
{
- e->makePublic(); // this is needed for both local and SMP collapsing
+ const KeyScope keyScope = reqFlags.refresh ? ksRevalidation : ksDefault;
+ e->makePublic(keyScope); // this is needed for both local and SMP collapsing
if (transients)
transients->startWriting(e, reqFlags, reqMethod);
debugs(20, 3, "may " << (transients && e->mem_obj->xitTable.index >= 0 ?
@@ -1003,6 +1004,12 @@
return found;
}
+bool
+StoreController::smpAware() const
+{
+ return memStore || (swapDir.getRaw() && swapDir->smpAware());
+}
+
StoreHashIndex::StoreHashIndex()
{
if (store_table)
@@ -1267,6 +1274,19 @@
return new StoreSearchHashIndex (this);
}
+bool
+StoreHashIndex::smpAware() const
+{
+ for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
+ // A mix is not supported, but we conservatively check every
+ // dir because features like collapsed revalidation should
+ // currently be disabled if any dir is SMP-aware
+ if (dir(i).smpAware())
+ return true;
+ }
+ return false;
+}
+
CBDATA_CLASS_INIT(StoreSearchHashIndex);
StoreSearchHashIndex::StoreSearchHashIndex(RefCount aSwapDir) :
diff -u -r -N squid-3.5.21/src/Store.h squid-3.5.22/src/Store.h
--- squid-3.5.21/src/Store.h 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/Store.h 2016-10-10 08:58:01.000000000 +1300
@@ -23,6 +23,7 @@
#include "MemObject.h"
#include "Range.h"
#include "RemovalPolicy.h"
+#include "store_key_md5.h"
#include "StoreIOBuffer.h"
#include "StoreStats.h"
@@ -93,9 +94,13 @@
void abort();
void unlink();
- void makePublic();
+ void makePublic(const KeyScope keyScope = ksDefault);
void makePrivate();
- void setPublicKey();
+ void setPublicKey(const KeyScope keyScope = ksDefault);
+ /// Resets existing public key to a public key with default scope,
+ /// releasing the old default-scope entry (if any).
+ /// Does nothing if the existing public key already has default scope.
+ void clearPublicKeyScope();
void setPrivateKey();
void expireNow();
void releaseRequest();
@@ -130,7 +135,7 @@
void registerAbort(STABH * cb, void *);
void reset();
void setMemStatus(mem_status_t);
- void timestampsSet();
+ bool timestampsSet();
void unregisterAbort();
void destroyMemObject();
int checkTooSmall();
@@ -138,7 +143,16 @@
void delayAwareRead(const Comm::ConnectionPointer &conn, char *buf, int len, AsyncCall::Pointer callback);
void setNoDelay (bool const);
- bool modifiedSince(HttpRequest * request) const;
+ void lastModified(const time_t when) { lastModified_ = when; }
+ /// \returns entry's 'effective' modification time
+ time_t lastModified() const {
+ // may still return -1 if timestamp is not set
+ return lastModified_ < 0 ? timestamp : lastModified_;
+ }
+ /// \returns a formatted string with entry's timestamps
+ const char *describeTimestamps() const;
+ // TODO: consider removing currently unsupported imslen parameter
+ bool modifiedSince(const time_t ims, const int imslen = -1) const;
/// has ETag matching at least one of the If-Match etags
bool hasIfMatchEtag(const HttpRequest &request) const;
/// has ETag matching at least one of the If-None-Match etags
@@ -155,7 +169,9 @@
time_t timestamp;
time_t lastref;
time_t expires;
- time_t lastmod;
+private:
+ time_t lastModified_; ///< received Last-Modified value or -1; use lastModified()
+public:
uint64_t swap_file_sz;
uint16_t refcount;
uint16_t flags;
@@ -228,6 +244,9 @@
private:
bool checkTooBig() const;
+ void forcePublicKey(const cache_key *newkey);
+ void adjustVary();
+ const cache_key *calcPublicKey(const KeyScope keyScope);
static MemAllocator *pool;
@@ -430,6 +449,9 @@
/// update a local collapsed entry with fresh info from this cache (if any)
virtual bool updateCollapsed(StoreEntry &collapsed) { return false; }
+ /// whether this storage is capable of serving multiple workers
+ virtual bool smpAware() const = 0;
+
private:
static RefCount CurrentRoot;
};
@@ -450,10 +472,10 @@
StoreEntry *storeGetPublic(const char *uri, const HttpRequestMethod& method);
/// \ingroup StoreAPI
-StoreEntry *storeGetPublicByRequest(HttpRequest * request);
+StoreEntry *storeGetPublicByRequest(HttpRequest * request, const KeyScope keyScope = ksDefault);
/// \ingroup StoreAPI
-StoreEntry *storeGetPublicByRequestMethod(HttpRequest * request, const HttpRequestMethod& method);
+StoreEntry *storeGetPublicByRequestMethod(HttpRequest * request, const HttpRequestMethod& method, const KeyScope keyScope = ksDefault);
/// \ingroup StoreAPI
/// Like storeCreatePureEntry(), but also locks the entry and sets entry key.
diff -u -r -N squid-3.5.21/src/StoreHashIndex.h squid-3.5.22/src/StoreHashIndex.h
--- squid-3.5.21/src/StoreHashIndex.h 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/StoreHashIndex.h 2016-10-10 08:58:01.000000000 +1300
@@ -59,6 +59,8 @@
virtual StoreSearch *search(String const url, HttpRequest *);
+ virtual bool smpAware() const;
+
private:
/* migration logic */
StorePointer store(int const x) const;
diff -u -r -N squid-3.5.21/src/store_key_md5.cc squid-3.5.22/src/store_key_md5.cc
--- squid-3.5.21/src/store_key_md5.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/store_key_md5.cc 2016-10-10 08:58:01.000000000 +1300
@@ -96,7 +96,7 @@
}
const cache_key *
-storeKeyPublic(const char *url, const HttpRequestMethod& method)
+storeKeyPublic(const char *url, const HttpRequestMethod& method, const KeyScope keyScope)
{
static cache_key digest[SQUID_MD5_DIGEST_LENGTH];
unsigned char m = (unsigned char) method.id();
@@ -104,18 +104,20 @@
SquidMD5Init(&M);
SquidMD5Update(&M, &m, sizeof(m));
SquidMD5Update(&M, (unsigned char *) url, strlen(url));
+ if (keyScope)
+ SquidMD5Update(&M, &keyScope, sizeof(keyScope));
SquidMD5Final(digest, &M);
return digest;
}
const cache_key *
-storeKeyPublicByRequest(HttpRequest * request)
+storeKeyPublicByRequest(HttpRequest * request, const KeyScope keyScope)
{
- return storeKeyPublicByRequestMethod(request, request->method);
+ return storeKeyPublicByRequestMethod(request, request->method, keyScope);
}
const cache_key *
-storeKeyPublicByRequestMethod(HttpRequest * request, const HttpRequestMethod& method)
+storeKeyPublicByRequestMethod(HttpRequest * request, const HttpRequestMethod& method, const KeyScope keyScope)
{
static cache_key digest[SQUID_MD5_DIGEST_LENGTH];
unsigned char m = (unsigned char) method.id();
@@ -125,6 +127,9 @@
SquidMD5Update(&M, &m, sizeof(m));
SquidMD5Update(&M, (unsigned char *) url, strlen(url));
+ if (keyScope)
+ SquidMD5Update(&M, &keyScope, sizeof(keyScope));
+
if (!request->vary_headers.isEmpty()) {
SquidMD5Update(&M, request->vary_headers.rawContent(), request->vary_headers.length());
debugs(20, 3, "updating public key by vary headers: " << request->vary_headers << " for: " << url);
diff -u -r -N squid-3.5.21/src/store_key_md5.h squid-3.5.22/src/store_key_md5.h
--- squid-3.5.21/src/store_key_md5.h 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/store_key_md5.h 2016-10-10 08:58:01.000000000 +1300
@@ -17,14 +17,19 @@
class HttpRequestMethod;
class HttpRequest;
+typedef enum {
+ ksDefault,
+ ksRevalidation
+} KeyScope;
+
cache_key *storeKeyDup(const cache_key *);
cache_key *storeKeyCopy(cache_key *, const cache_key *);
void storeKeyFree(const cache_key *);
const cache_key *storeKeyScan(const char *);
const char *storeKeyText(const cache_key *);
-const cache_key *storeKeyPublic(const char *, const HttpRequestMethod&);
-const cache_key *storeKeyPublicByRequest(HttpRequest *);
-const cache_key *storeKeyPublicByRequestMethod(HttpRequest *, const HttpRequestMethod&);
+const cache_key *storeKeyPublic(const char *, const HttpRequestMethod&, const KeyScope keyScope = ksDefault);
+const cache_key *storeKeyPublicByRequest(HttpRequest *, const KeyScope keyScope = ksDefault);
+const cache_key *storeKeyPublicByRequestMethod(HttpRequest *, const HttpRequestMethod&, const KeyScope keyScope = ksDefault);
const cache_key *storeKeyPrivate(const char *, const HttpRequestMethod&, int);
int storeKeyHashBuckets(int);
int storeKeyNull(const cache_key *);
diff -u -r -N squid-3.5.21/src/store_rebuild.cc squid-3.5.22/src/store_rebuild.cc
--- squid-3.5.21/src/store_rebuild.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/store_rebuild.cc 2016-10-10 08:58:01.000000000 +1300
@@ -254,7 +254,7 @@
what->timestamp = tmp->timestamp;
what->lastref = tmp->lastref;
what->expires = tmp->expires;
- what->lastmod = tmp->lastmod;
+ what->lastModified(tmp->lastmod);
what->swap_file_sz = tmp->swap_file_sz;
what->refcount = tmp->refcount;
what->flags = tmp->flags;
diff -u -r -N squid-3.5.21/src/SwapDir.h squid-3.5.22/src/SwapDir.h
--- squid-3.5.21/src/SwapDir.h 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/SwapDir.h 2016-10-10 08:58:01.000000000 +1300
@@ -51,6 +51,7 @@
virtual void memoryDisconnect(StoreEntry &e);
virtual void allowCollapsing(StoreEntry *e, const RequestFlags &reqFlags, const HttpRequestMethod &reqMethod);
virtual void syncCollapsed(const sfileno xitIndex);
+ virtual bool smpAware() const;
virtual void init();
@@ -158,6 +159,7 @@
virtual void getStats(StoreInfoStats &stats) const;
virtual void stat (StoreEntry &anEntry) const;
virtual StoreSearch *search(String const url, HttpRequest *) = 0;
+ virtual bool smpAware() const { return false; }
/* migrated from store_dir.cc */
bool objectSizeIsAcceptable(int64_t objsize) const;
diff -u -r -N squid-3.5.21/src/tests/stub_store.cc squid-3.5.22/src/tests/stub_store.cc
--- squid-3.5.21/src/tests/stub_store.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/tests/stub_store.cc 2016-10-10 08:58:01.000000000 +1300
@@ -42,9 +42,9 @@
void StoreEntry::trimMemory(const bool preserveSwappable) STUB
void StoreEntry::abort() STUB
void StoreEntry::unlink() STUB
-void StoreEntry::makePublic() STUB
+void StoreEntry::makePublic(const KeyScope keyScope) STUB
void StoreEntry::makePrivate() STUB
-void StoreEntry::setPublicKey() STUB
+void StoreEntry::setPublicKey(const KeyScope keyScope) STUB
void StoreEntry::setPrivateKey() STUB
void StoreEntry::expireNow() STUB
void StoreEntry::releaseRequest() STUB
@@ -67,13 +67,13 @@
void StoreEntry::registerAbort(STABH * cb, void *) STUB
void StoreEntry::reset() STUB
void StoreEntry::setMemStatus(mem_status_t) STUB
-void StoreEntry::timestampsSet() STUB
+bool StoreEntry::timestampsSet() STUB_RETVAL(false)
void StoreEntry::unregisterAbort() STUB
void StoreEntry::destroyMemObject() STUB
int StoreEntry::checkTooSmall() STUB_RETVAL(0)
void StoreEntry::delayAwareRead(const Comm::ConnectionPointer&, char *buf, int len, AsyncCall::Pointer callback) STUB
void StoreEntry::setNoDelay (bool const) STUB
-bool StoreEntry::modifiedSince(HttpRequest * request) const STUB_RETVAL(false)
+bool StoreEntry::modifiedSince(const time_t ims, const int imslen) const STUB_RETVAL(false);
bool StoreEntry::hasIfMatchEtag(const HttpRequest &request) const STUB_RETVAL(false)
bool StoreEntry::hasIfNoneMatchEtag(const HttpRequest &request) const STUB_RETVAL(false)
RefCount StoreEntry::store() const STUB_RETVAL(NULL)
@@ -125,8 +125,8 @@
size_t storeEntryInUse() STUB_RETVAL(0)
void storeEntryReplaceObject(StoreEntry *, HttpReply *) STUB
StoreEntry *storeGetPublic(const char *uri, const HttpRequestMethod& method) STUB_RETVAL(NULL)
-StoreEntry *storeGetPublicByRequest(HttpRequest * request) STUB_RETVAL(NULL)
-StoreEntry *storeGetPublicByRequestMethod(HttpRequest * request, const HttpRequestMethod& method) STUB_RETVAL(NULL)
+StoreEntry *storeGetPublicByRequest(HttpRequest * request, const KeyScope keyScope) STUB_RETVAL(NULL)
+StoreEntry *storeGetPublicByRequestMethod(HttpRequest * request, const HttpRequestMethod& method, const KeyScope keyScope) STUB_RETVAL(NULL)
StoreEntry *storeCreateEntry(const char *, const char *, const RequestFlags &, const HttpRequestMethod&) STUB_RETVAL(NULL)
StoreEntry *storeCreatePureEntry(const char *storeId, const char *logUrl, const RequestFlags &, const HttpRequestMethod&) STUB_RETVAL(NULL)
void storeInit(void) STUB
diff -u -r -N squid-3.5.21/src/tests/testRock.cc squid-3.5.22/src/tests/testRock.cc
--- squid-3.5.21/src/tests/testRock.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/tests/testRock.cc 2016-10-10 08:58:01.000000000 +1300
@@ -143,8 +143,6 @@
httpHeaderInitModule(); /* must go before any header processing (e.g. the one in errorInitialize) */
- httpReplyInitModule(); /* must go before accepting replies */
-
mem_policy = createRemovalPolicy(Config.replPolicy);
inited = true;
diff -u -r -N squid-3.5.21/src/tests/testStoreController.cc squid-3.5.22/src/tests/testStoreController.cc
--- squid-3.5.21/src/tests/testStoreController.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/tests/testStoreController.cc 2016-10-10 08:58:01.000000000 +1300
@@ -113,7 +113,7 @@
e->lastref = squid_curtime;
e->timestamp = squid_curtime;
e->expires = squid_curtime;
- e->lastmod = squid_curtime;
+ e->lastModified(squid_curtime);
e->refcount = 1;
EBIT_CLR(e->flags, RELEASE_REQUEST);
EBIT_CLR(e->flags, KEY_PRIVATE);
diff -u -r -N squid-3.5.21/src/tests/testStore.h squid-3.5.22/src/tests/testStore.h
--- squid-3.5.21/src/tests/testStore.h 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/tests/testStore.h 2016-10-10 08:58:01.000000000 +1300
@@ -76,6 +76,8 @@
virtual bool dereference(StoreEntry &, bool) { return true; }
virtual StoreSearch *search(String const url, HttpRequest *);
+
+ virtual bool smpAware() const { return false; }
};
typedef RefCount TestStorePointer;
diff -u -r -N squid-3.5.21/src/tests/testStoreHashIndex.cc squid-3.5.22/src/tests/testStoreHashIndex.cc
--- squid-3.5.21/src/tests/testStoreHashIndex.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/tests/testStoreHashIndex.cc 2016-10-10 08:58:01.000000000 +1300
@@ -94,7 +94,7 @@
e->lastref = squid_curtime;
e->timestamp = squid_curtime;
e->expires = squid_curtime;
- e->lastmod = squid_curtime;
+ e->lastModified(squid_curtime);
e->refcount = 1;
EBIT_CLR(e->flags, RELEASE_REQUEST);
EBIT_CLR(e->flags, KEY_PRIVATE);
diff -u -r -N squid-3.5.21/src/tests/testUfs.cc squid-3.5.22/src/tests/testUfs.cc
--- squid-3.5.21/src/tests/testUfs.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/tests/testUfs.cc 2016-10-10 08:58:01.000000000 +1300
@@ -75,8 +75,6 @@
httpHeaderInitModule(); /* must go before any header processing (e.g. the one in errorInitialize) */
- httpReplyInitModule(); /* must go before accepting replies */
-
inited = true;
}
diff -u -r -N squid-3.5.21/src/Transients.cc squid-3.5.22/src/Transients.cc
--- squid-3.5.21/src/Transients.cc 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/Transients.cc 2016-10-10 08:58:01.000000000 +1300
@@ -197,7 +197,8 @@
e->mem_obj->xitTable.io = MemObject::ioReading;
e->mem_obj->xitTable.index = index;
- e->setPublicKey();
+ // TODO: Support collapsed revalidation for SMP-aware caches
+ e->setPublicKey(ksDefault);
assert(e->key);
// How do we know its SMP- and not just locally-collapsed? A worker gets
diff -u -r -N squid-3.5.21/src/Transients.h squid-3.5.22/src/Transients.h
--- squid-3.5.21/src/Transients.h 2016-09-09 06:56:46.000000000 +1200
+++ squid-3.5.22/src/Transients.h 2016-10-10 08:58:01.000000000 +1300
@@ -72,6 +72,7 @@
virtual bool dereference(StoreEntry &, bool);
virtual void markForUnlink(StoreEntry &e);
virtual void maintain();
+ virtual bool smpAware() const { return true; }
static int64_t EntryLimit();