diff -u -r -N squid-4.0.25/ChangeLog squid-4.1/ChangeLog --- squid-4.0.25/ChangeLog 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/ChangeLog 2018-07-02 15:26:07.000000000 +1200 @@ -1,3 +1,10 @@ +Changes to squid-4.1 (02 Jul 2018): + + - Bug 4223: fixed retries of failed re-forwardable transactions + - Bug 4791: Build failure on MacOS + - Fix --with-netfilter-conntrack error message + - ... and many documentation updates + Changes to squid-4.0.25 (11 Jun 2018): - Regression Bug 4855: querying private entries for HTCP/ICP diff -u -r -N squid-4.0.25/compat/cpu.h squid-4.1/compat/cpu.h --- squid-4.0.25/compat/cpu.h 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/compat/cpu.h 2018-07-02 15:26:07.000000000 +1200 @@ -18,7 +18,7 @@ #if !HAVE_CPU_AFFINITY /* failing replacements to minimize the number of if-HAVE_CPU_AFFINITYs */ -#if !defined(__cpu_set_t_defined) +#if !HAVE_CPU_SET_T typedef struct { int bits; } cpu_set_t; diff -u -r -N squid-4.0.25/configure squid-4.1/configure --- squid-4.0.25/configure 2018-06-12 04:48:04.000000000 +1200 +++ squid-4.1/configure 2018-07-02 15:32:06.000000000 +1200 @@ -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 4.0.25. +# Generated by GNU Autoconf 2.69 for Squid Web Proxy 4.1. # # Report bugs to . # @@ -595,8 +595,8 @@ # Identity of this package. PACKAGE_NAME='Squid Web Proxy' PACKAGE_TARNAME='squid' -PACKAGE_VERSION='4.0.25' -PACKAGE_STRING='Squid Web Proxy 4.0.25' +PACKAGE_VERSION='4.1' +PACKAGE_STRING='Squid Web Proxy 4.1' PACKAGE_BUGREPORT='http://bugs.squid-cache.org/' PACKAGE_URL='' @@ -1647,7 +1647,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 4.0.25 to adapt to many kinds of systems. +\`configure' configures Squid Web Proxy 4.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1718,7 +1718,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Squid Web Proxy 4.0.25:";; + short | recursive ) echo "Configuration of Squid Web Proxy 4.1:";; esac cat <<\_ACEOF @@ -2147,7 +2147,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Squid Web Proxy configure 4.0.25 +Squid Web Proxy configure 4.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -3251,7 +3251,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 4.0.25, which was +It was created by Squid Web Proxy $as_me 4.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -4118,7 +4118,7 @@ # Define the identity of the package. PACKAGE='squid' - VERSION='4.0.25' + VERSION='4.1' cat >>confdefs.h <<_ACEOF @@ -33786,7 +33786,7 @@ ;; *) if test ! -d "$withval" ; then - as_fn_error $? "--without-netfilter-conntrack path does not point to a directory" "$LINENO" 5 + as_fn_error $? "--with-netfilter-conntrack path does not point to a directory" "$LINENO" 5 fi squid_opt_netfilterconntrackpath=$withval LDFLAGS="-L$squid_opt_netfilterconntrackpath/lib $LDFLAGS" @@ -38732,6 +38732,19 @@ fi +ac_fn_cxx_check_type "$LINENO" "cpu_set_t" "ac_cv_type_cpu_set_t" " +#if HAVE_SCHED_H +#include +#endif + +" +if test "x$ac_cv_type_cpu_set_t" = xyes; then : + +$as_echo "#define HAVE_CPU_SET_T 1" >>confdefs.h + +fi + + # check for compiler support of %zu printf macro { $as_echo "$as_me:${as_lineno-$LINENO}: checking for compiler %zu support" >&5 @@ -43819,7 +43832,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 4.0.25, which was +This file was extended by Squid Web Proxy $as_me 4.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -43885,7 +43898,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 4.0.25 +Squid Web Proxy config.status 4.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -u -r -N squid-4.0.25/configure.ac squid-4.1/configure.ac --- squid-4.0.25/configure.ac 2018-06-12 04:48:04.000000000 +1200 +++ squid-4.1/configure.ac 2018-07-02 15:32:06.000000000 +1200 @@ -5,7 +5,7 @@ ## Please see the COPYING and CONTRIBUTORS files for details. ## -AC_INIT([Squid Web Proxy],[4.0.25],[http://bugs.squid-cache.org/],[squid]) +AC_INIT([Squid Web Proxy],[4.1],[http://bugs.squid-cache.org/],[squid]) AC_PREREQ(2.61) AC_CONFIG_HEADERS([include/autoconf.h]) AC_CONFIG_AUX_DIR(cfgaux) @@ -2333,7 +2333,7 @@ ;; *) if test ! -d "$withval" ; then - AC_MSG_ERROR([--without-netfilter-conntrack path does not point to a directory]) + AC_MSG_ERROR([--with-netfilter-conntrack path does not point to a directory]) fi squid_opt_netfilterconntrackpath=$withval LDFLAGS="-L$squid_opt_netfilterconntrackpath/lib $LDFLAGS" @@ -3026,6 +3026,13 @@ #include #include ]) +AC_CHECK_TYPE(cpu_set_t, + AC_DEFINE(HAVE_CPU_SET_T,1,[cpu_set_t is defined by the system headers]),,[ +#if HAVE_SCHED_H +#include +#endif +]) + # check for compiler support of %zu printf macro AH_TEMPLATE(PRIuSIZE,[Compiler supports %zu printf macro]) AC_MSG_CHECKING([for compiler %zu support]) diff -u -r -N squid-4.0.25/CONTRIBUTORS squid-4.1/CONTRIBUTORS --- squid-4.0.25/CONTRIBUTORS 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/CONTRIBUTORS 2018-07-02 15:26:07.000000000 +1200 @@ -10,6 +10,8 @@ Aleksa Aleksa ??u??uli?? Alexander B. Demenshin + Alexander Gozman + Alexander Gozman Alexander Komyagin Alexander Lukyanov Alexander Lukyanov @@ -20,15 +22,20 @@ Alexis Robert Alex Rousskov Alex Rousskov + Alex Wu Alin Nastac Alter + Amos Jeffries Amos Jeffries Amos Jeffries + Amos Jeffries Amos Anatoli Andrea Gagliardi + Andre Albsmeier Andreas Jaeger Andreas Lamprecht + Andreas Weigel Andres Kroonmaa Andrew Balabohin Andrew Beverley @@ -36,7 +43,9 @@ Andrew Evdokimov Andrew Hoying Andrew Tridgell + Andrey Andrey Shorin + Anonymous Anonymous Pootle User Anonymous Ansgar Hockmann @@ -52,6 +61,7 @@ Assar Westerlund Automatic source maintenance Axel Westerhold + Aymeric Vincent Barry Dobyns Benjamin Kerensa Benno Rice @@ -67,11 +77,13 @@ Brian Bruce Murphy Carson Gaspar (carson@lehman.com, carson@cs.columbia.edu) + Carsten Grzemba Cephas Chad E. Naugle Chad Naugle Changming Chao + Chris Addie Chris Hills Christian Wittmer Christopher Kerr @@ -79,15 +91,19 @@ Christoph Lechleitner Christos Tsantilas Christos Tsantilas + Chudy Fernandez Cloyce Clytie Siddall Colin Coe Constantin Rack Cord Beermann + Craig Gowing Daniel Beschorner Daniel O'Callaghan Daniel Walter + Dan Searle Dan Searle + Dave Dykstra David Hill David Isaacs David J N Begley @@ -99,23 +115,29 @@ Dennis Glatting Dhaval Varia Diego Woitasen + Diogenes S. Jesus D Kazarov Dmitry Kurochkin Don Hopkins Doug Dixon Doug Urner Dragutin Cirkovic + DrDaveD drserge Dr. Tilmann Bubeck Duane Wessels Dustin J. Mitchell Ed Knowles + Eduard Bagdasaryan + Eduard Bagdasaryan Edward Chernenko Edward Moy + Egervary Gergely Eldar Akchurin Eliezer Croitoru Elmar Vonlanthen Emilio Casbas + Emmanuel Fuste Endre Balint Nagy Eray Aslan Eray Aslan @@ -144,6 +166,7 @@ Fred F Wolff Fyodor + Garri Djavadyan Geoff Keating George Michaelson Georgy Salnikov @@ -171,30 +194,38 @@ Henrik Nordstrom Hide Nagaoka HONDA Hirofumi + huaraz Hussam Al-Tayeb Ian Castle + Ian Clark Ian Turner Igor Vinokurov IIDA Yosiaki + Ingo Schwarze isaac Isnard + Ivan Larionov Ivan Mas??r Jakob Bohm Jakub Wilk James Bowe James Brotchie James R Grinter + Jamie Strandboge Jan Klemkow Jan Niehusmann Jan Sievers + Javad Kouhi Jean-Francois Micouleau Jean-Gabriel Dick Jean-Philippe Menil + Jeff Licquia Jens-S. V?ckler Jeremy Allison Jerry Murdock Jiri Skala Jiri Skala + jltallon Joachim Bauch Joachim Bauch (mail@joachim-bauch.de) Joao Alves Neto @@ -205,9 +236,10 @@ Joe Ramey Joerg Lehrke Johnathan Conley + John Dilley John@MCC.ac.uk + John M Cooper John@Pharmweb.NET - John Dilley John Saunders John Xue Jonathan Larmour @@ -215,6 +247,7 @@ Jon Kinred Jon Thackray Jorge Ivan Burgos Aguilar + Jose Luis Godoy Jose-Marcio Martins da Cruz Joshua Root Joshua Root @@ -231,8 +264,10 @@ Lab10 Laszlo Attilla Toth Leeann Bent + Leonardo Taccari Leonid Evdokimov libit + Lubos Uhliarik Luigi Gangitano Luis Daniel Lucio Quiroz Lukas B??gelei @@ -242,6 +277,8 @@ Marcello Romani Marcin Wisnicki Marco Beck + Marcos Mello + Marcos Mello Marcus Kool Marc van Selm Marin Stavrev @@ -252,6 +289,7 @@ Marko Mark Treacy Markus Gyger + Markus Mayer Markus Moeller Markus Moeller (markus_moeller at compuserve.com) Markus Rietzler @@ -261,6 +299,7 @@ Martin Huter Martin Huter Martin Stolle + Martin von Gagern Masashi Fujita Massimo Zito Mathias Fischer @@ -270,6 +309,7 @@ Max Okumoto Merik Karman + Michael Buchau Michael Cunningham Michael Lupp Michael Mansour @@ -278,6 +318,7 @@ Michael van Elst Michael Weiser Michal Luscon + Michele Bergonzoni Miguel A.L. Paraz Mike Groeneweg Mike Mitchell @@ -286,6 +327,7 @@ Milen Pankov Ming Fu Miquel van Smoorenburg + mkishi Moez Mahfoudh Mohsen Saeedi Mukaigawa Shin'ichi @@ -303,8 +345,11 @@ Olivier W. OpenSolaris Project Oskar Pearson + Patrick Welche + Paulo Matias Paul Z Pavel Timofeev + Pavel Timofeev Pawel Worach Pedro Lineu Orso Pedro Ribeiro @@ -326,6 +371,7 @@ Rafael Martinez Rafael Martinez Torres Rafal Ramocki + Rainer Tammer Rajiv Desai Ralf Wildenhues Ralph Loader @@ -355,7 +401,9 @@ R Phillips Russell Street Russell Vincent + Rusty Bird Ryan Troll + Rybakov Andrey Samba Project Santiago Garcia Mantinan Scott James Remnant @@ -367,8 +415,13 @@ Sergio Rabellino Shigechika Aikawa Silamael + Simon Deziel + SquidAdm + squidadm Stefan Fritsch + Stefan Kruger Stefano Cordibella + Stephen Baynes Stephen R. van den Berg Stephen Thorne Steve Bennett @@ -380,9 +433,12 @@ Stuart Henderson Stuart Henderson Susant Sahani + Sven Eisenberg Svenx Taavi Talvik + Takahiro Kambe Taketo Kabe + tangqinghao The Measurement Factory The Squid Software Foundation Thomas De Schampheleire @@ -399,10 +455,13 @@ Todd C. Miller Tomas Hozza Tony Lorimer + Trever Adams Tsantilas Christos Unknown + Unknown - Debian Project Unknown FreeBSD Contributor Unknown - NetBSD Project + Vadim Aleksandrov Various Various Translators Victor Jose Hernandez Gomez @@ -410,11 +469,13 @@ Vincent Regnard Vitaliy Matytsyn (main) Vitaliy Matytsyn + Vitaly Lavrov vollkommen Walter Wang DaQing Warren Baker Wesha + William Lima Will Roberts Wojciech Zatorski Wojtek Sylwestrzak @@ -424,4 +485,5 @@ yabuki Yannick Bergeron Yuhua Wu + Yuriy M. Kaminskiy Zhanpeng Chen diff -u -r -N squid-4.0.25/doc/release-notes/release-4.html squid-4.1/doc/release-notes/release-4.html --- squid-4.0.25/doc/release-notes/release-4.html 2018-06-12 04:56:17.000000000 +1200 +++ squid-4.1/doc/release-notes/release-4.html 2018-07-02 15:39:05.000000000 +1200 @@ -2,10 +2,10 @@ - Squid 4.0.25 release notes + Squid 4.1 release notes -

Squid 4.0.25 release notes

+

Squid 4.1 release notes

Squid Developers


@@ -63,13 +63,11 @@

1. Notice

-

The Squid Team are pleased to announce the release of Squid-4.0.25 for testing.

+

The Squid Team are pleased to announce the release of Squid-4.1 for testing.

This new release is available for download from http://www.squid-cache.org/Versions/v4/ or the mirrors.

-

While this release is not deemed ready for production use, we believe it is ready for wider testing by the community.

-

We welcome feedback and bug reports. If you find a bug, please see http://wiki.squid-cache.org/SquidFaq/BugReporting for how to submit a report with a stack trace.

@@ -77,7 +75,7 @@

1.1 Known issues

-

Although this release is deemed good enough for use in many setups, please note the existence of +

Although this release is deemed good enough for use in production, please note the existence of open bugs against Squid-4.

This release adds a dependency on C++11 support in any compiler used to build Squid. @@ -165,11 +163,11 @@ when an old TLS version is requested by the remote endpoint.

The system Trusted CAs are no longer used by default when verifying client -certificates. The cafile= option should be used instead to load -the specific CA which signed acceptible client certificates explicitly, +certificates. The cafile= option should be used instead to +explicitly load the specific CA which signed acceptible client certificates, even if that CA is one of the system Trusted CAs. The tls-default-ca option can be used to restore the old -behaviour explicitly if needed.

+behaviour if needed.

2.4 Helper Binary Changes @@ -192,8 +190,9 @@

The ssl_crtd helper has been renamed to security_file_certgen and is now built and installed by default whenever OpenSSL support is enabled. Building the helper can be controlled using the --enable-security-cert-generators="file" -option. -NOTE: The --enable-ssl-crtd option is still required to enable the +option.

+ +

NOTE: The --enable-ssl-crtd option is still required to enable the sslcrtd_program helper interface within Squid that uses the helper.

The ntlm_smb_lm_auth helper is now built using --enable-auth-ntlm="SMB_LM". @@ -219,8 +218,8 @@

Use of C++11 atomic operations instead of GNU atomics allows a wider range of operating systems and compilers to build Squid SMP and multi-process features. -However this does require a C++11 or C++0x compiler with a recent version of -the C++ standard library.

+However this does require a C++11 compiler with a recent version of the C++ +standard library.

IpcIo and Mmapped disk I/O modules are now auto-detected properly which enables Rock storage on more systems by default than previously.

@@ -269,7 +268,10 @@

Advanced configuration with specific selection of ciphers and similar settings should still work, but needs the GnuTLS Priority Strings instead of -the OpenSSL options when using GnuTLS.

+the OpenSSL options when using GnuTLS. +See +GnuTLS manual +for more details.

2.9 ESI Custom Parser removal @@ -344,7 +346,7 @@ connections. For example to HTTPS servers.

url_rewrite_timeout
-

Squid times active requests to redirector. This option sets +

Squid times active requests to redirector. This directive sets the timeout value and the Squid reaction to a timed out request.

@@ -359,7 +361,7 @@
access_log

TCP accept(2) errors logged with URI error:accept-client-connection.

Unused connections received in http_port or https_port -or transactions terminated before reading[parsing] request headers +or transactions terminated before reading[parsing] request headers are logged with URI error:transaction-end-before-headers.

New option rotate= to control the number of log file rotations to make when -k rotate command is received. Default is to diff -u -r -N squid-4.0.25/include/autoconf.h.in squid-4.1/include/autoconf.h.in --- squid-4.0.25/include/autoconf.h.in 2018-06-12 04:47:56.000000000 +1200 +++ squid-4.1/include/autoconf.h.in 2018-07-02 15:32:00.000000000 +1200 @@ -137,6 +137,9 @@ /* Support setting CPU affinity for workers */ #undef HAVE_CPU_AFFINITY +/* cpu_set_t is defined by the system headers */ +#undef HAVE_CPU_SET_T + /* Define to 1 if you have the `crypt' function. */ #undef HAVE_CRYPT diff -u -r -N squid-4.0.25/include/version.h squid-4.1/include/version.h --- squid-4.0.25/include/version.h 2018-06-12 04:48:04.000000000 +1200 +++ squid-4.1/include/version.h 2018-07-02 15:32:06.000000000 +1200 @@ -7,7 +7,7 @@ */ #ifndef SQUID_RELEASE_TIME -#define SQUID_RELEASE_TIME 1528735673 +#define SQUID_RELEASE_TIME 1530502317 #endif /* diff -u -r -N squid-4.0.25/RELEASENOTES.html squid-4.1/RELEASENOTES.html --- squid-4.0.25/RELEASENOTES.html 2018-06-12 04:56:17.000000000 +1200 +++ squid-4.1/RELEASENOTES.html 2018-07-02 15:39:05.000000000 +1200 @@ -2,10 +2,10 @@ - Squid 4.0.25 release notes + Squid 4.1 release notes -

Squid 4.0.25 release notes

+

Squid 4.1 release notes

Squid Developers


@@ -63,13 +63,11 @@

1. Notice

-

The Squid Team are pleased to announce the release of Squid-4.0.25 for testing.

+

The Squid Team are pleased to announce the release of Squid-4.1 for testing.

This new release is available for download from http://www.squid-cache.org/Versions/v4/ or the mirrors.

-

While this release is not deemed ready for production use, we believe it is ready for wider testing by the community.

-

We welcome feedback and bug reports. If you find a bug, please see http://wiki.squid-cache.org/SquidFaq/BugReporting for how to submit a report with a stack trace.

@@ -77,7 +75,7 @@

1.1 Known issues

-

Although this release is deemed good enough for use in many setups, please note the existence of +

Although this release is deemed good enough for use in production, please note the existence of open bugs against Squid-4.

This release adds a dependency on C++11 support in any compiler used to build Squid. @@ -165,11 +163,11 @@ when an old TLS version is requested by the remote endpoint.

The system Trusted CAs are no longer used by default when verifying client -certificates. The cafile= option should be used instead to load -the specific CA which signed acceptible client certificates explicitly, +certificates. The cafile= option should be used instead to +explicitly load the specific CA which signed acceptible client certificates, even if that CA is one of the system Trusted CAs. The tls-default-ca option can be used to restore the old -behaviour explicitly if needed.

+behaviour if needed.

2.4 Helper Binary Changes @@ -192,8 +190,9 @@

The ssl_crtd helper has been renamed to security_file_certgen and is now built and installed by default whenever OpenSSL support is enabled. Building the helper can be controlled using the --enable-security-cert-generators="file" -option. -NOTE: The --enable-ssl-crtd option is still required to enable the +option.

+ +

NOTE: The --enable-ssl-crtd option is still required to enable the sslcrtd_program helper interface within Squid that uses the helper.

The ntlm_smb_lm_auth helper is now built using --enable-auth-ntlm="SMB_LM". @@ -219,8 +218,8 @@

Use of C++11 atomic operations instead of GNU atomics allows a wider range of operating systems and compilers to build Squid SMP and multi-process features. -However this does require a C++11 or C++0x compiler with a recent version of -the C++ standard library.

+However this does require a C++11 compiler with a recent version of the C++ +standard library.

IpcIo and Mmapped disk I/O modules are now auto-detected properly which enables Rock storage on more systems by default than previously.

@@ -269,7 +268,10 @@

Advanced configuration with specific selection of ciphers and similar settings should still work, but needs the GnuTLS Priority Strings instead of -the OpenSSL options when using GnuTLS.

+the OpenSSL options when using GnuTLS. +See +GnuTLS manual +for more details.

2.9 ESI Custom Parser removal @@ -344,7 +346,7 @@ connections. For example to HTTPS servers.

url_rewrite_timeout
-

Squid times active requests to redirector. This option sets +

Squid times active requests to redirector. This directive sets the timeout value and the Squid reaction to a timed out request.

@@ -359,7 +361,7 @@
access_log

TCP accept(2) errors logged with URI error:accept-client-connection.

Unused connections received in http_port or https_port -or transactions terminated before reading[parsing] request headers +or transactions terminated before reading[parsing] request headers are logged with URI error:transaction-end-before-headers.

New option rotate= to control the number of log file rotations to make when -k rotate command is received. Default is to diff -u -r -N squid-4.0.25/src/acl/Asn.cc squid-4.1/src/acl/Asn.cc --- squid-4.0.25/src/acl/Asn.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/acl/Asn.cc 2018-07-02 15:26:07.000000000 +1200 @@ -235,7 +235,7 @@ static void asnCacheStart(int as) { - // TODO: use class URL instead of generating a string and re-parsing + // TODO: use class AnyP::Uri instead of generating a string and re-parsing LOCAL_ARRAY(char, asres, 4096); StoreEntry *e; ASState *asState = new ASState; diff -u -r -N squid-4.0.25/src/acl/DomainData.cc squid-4.1/src/acl/DomainData.cc --- squid-4.0.25/src/acl/DomainData.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/acl/DomainData.cc 2018-07-02 15:26:07.000000000 +1200 @@ -11,10 +11,10 @@ #include "squid.h" #include "acl/Checklist.h" #include "acl/DomainData.h" +#include "anyp/Uri.h" #include "cache_cf.h" #include "ConfigParser.h" #include "Debug.h" -#include "src/URL.h" #include "util.h" template diff -u -r -N squid-4.0.25/src/acl/external/delayer/ext_delayer_acl.8 squid-4.1/src/acl/external/delayer/ext_delayer_acl.8 --- squid-4.0.25/src/acl/external/delayer/ext_delayer_acl.8 2018-06-12 04:56:18.000000000 +1200 +++ squid-4.1/src/acl/external/delayer/ext_delayer_acl.8 2018-07-02 15:39:06.000000000 +1200 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EXT_DELAYER_ACL 8" -.TH EXT_DELAYER_ACL 8 "2018-06-11" "perl v5.26.2" "User Contributed Perl Documentation" +.TH EXT_DELAYER_ACL 8 "2018-07-02" "perl v5.26.2" "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-4.0.25/src/acl/external/SQL_session/ext_sql_session_acl.8 squid-4.1/src/acl/external/SQL_session/ext_sql_session_acl.8 --- squid-4.0.25/src/acl/external/SQL_session/ext_sql_session_acl.8 2018-06-12 04:56:19.000000000 +1200 +++ squid-4.1/src/acl/external/SQL_session/ext_sql_session_acl.8 2018-07-02 15:39:06.000000000 +1200 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EXT_SQL_SESSION_ACL 8" -.TH EXT_SQL_SESSION_ACL 8 "2018-06-11" "perl v5.26.2" "User Contributed Perl Documentation" +.TH EXT_SQL_SESSION_ACL 8 "2018-07-02" "perl v5.26.2" "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-4.0.25/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.8 squid-4.1/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.8 --- squid-4.0.25/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.8 2018-06-12 04:56:19.000000000 +1200 +++ squid-4.1/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.8 2018-07-02 15:39:06.000000000 +1200 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EXT_WBINFO_GROUP_ACL 8" -.TH EXT_WBINFO_GROUP_ACL 8 "2018-06-11" "perl v5.26.2" "User Contributed Perl Documentation" +.TH EXT_WBINFO_GROUP_ACL 8 "2018-07-02" "perl v5.26.2" "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-4.0.25/src/acl/ServerName.cc squid-4.1/src/acl/ServerName.cc --- squid-4.0.25/src/acl/ServerName.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/acl/ServerName.cc 2018-07-02 15:26:07.000000000 +1200 @@ -22,7 +22,6 @@ #include "ssl/bio.h" #include "ssl/ServerBump.h" #include "ssl/support.h" -#include "URL.h" // Compare function for tree search algorithms static int diff -u -r -N squid-4.0.25/src/acl/Url.cc squid-4.1/src/acl/Url.cc --- squid-4.0.25/src/acl/Url.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/acl/Url.cc 2018-07-02 15:26:07.000000000 +1200 @@ -14,7 +14,6 @@ #include "acl/Url.h" #include "HttpRequest.h" #include "rfc1738.h" -#include "src/URL.h" int ACLUrlStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) diff -u -r -N squid-4.0.25/src/adaptation/ecap/MessageRep.cc squid-4.1/src/adaptation/ecap/MessageRep.cc --- squid-4.0.25/src/adaptation/ecap/MessageRep.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/adaptation/ecap/MessageRep.cc 2018-07-02 15:26:07.000000000 +1200 @@ -20,7 +20,6 @@ #include "adaptation/ecap/MessageRep.h" #include "adaptation/ecap/XactionRep.h" #include "base/TextException.h" -#include "URL.h" /* HeaderRep */ @@ -199,8 +198,8 @@ void Adaptation::Ecap::RequestLineRep::uri(const Area &aUri) { - // TODO: if method is not set, URL::parse will assume it is not connect; - // Can we change URL::parse API to remove the method parameter? + // TODO: if method is not set, AnyP::Uri::parse will assume it is not connect; + // Can we change AnyP::Uri::parse API to remove the method parameter? const char *buf = aUri.toString().c_str(); const bool ok = theMessage.url.parse(theMessage.method, buf); Must(ok); diff -u -r -N squid-4.0.25/src/adaptation/icap/ModXact.cc squid-4.1/src/adaptation/icap/ModXact.cc --- squid-4.0.25/src/adaptation/icap/ModXact.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/adaptation/icap/ModXact.cc 2018-07-02 15:26:07.000000000 +1200 @@ -32,7 +32,6 @@ #include "HttpRequest.h" #include "MasterXaction.h" #include "SquidTime.h" -#include "URL.h" // flow and terminology: // HTTP| --> receive --> encode --> write --> |network diff -u -r -N squid-4.0.25/src/adaptation/ServiceConfig.cc squid-4.1/src/adaptation/ServiceConfig.cc --- squid-4.0.25/src/adaptation/ServiceConfig.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/adaptation/ServiceConfig.cc 2018-07-02 15:26:07.000000000 +1200 @@ -189,7 +189,7 @@ Adaptation::ServiceConfig::grokUri(const char *value) { // TODO: find core code that parses URLs and extracts various parts - // AYJ: most of this is duplicate of URL::parse() in src/url.cc + // AYJ: most of this is duplicate of AnyP::Uri::parse() if (!value || !*value) { debugs(3, DBG_CRITICAL, HERE << cfg_filename << ':' << config_lineno << ": " << diff -u -r -N squid-4.0.25/src/anyp/forward.h squid-4.1/src/anyp/forward.h --- squid-4.0.25/src/anyp/forward.h 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/anyp/forward.h 2018-07-02 15:26:07.000000000 +1200 @@ -17,6 +17,7 @@ class PortCfg; typedef RefCount PortCfgPointer; +class Uri; class UriScheme; } // namespace AnyP diff -u -r -N squid-4.0.25/src/anyp/Makefile.am squid-4.1/src/anyp/Makefile.am --- squid-4.0.25/src/anyp/Makefile.am 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/anyp/Makefile.am 2018-07-02 15:26:07.000000000 +1200 @@ -18,6 +18,8 @@ ProtocolType.h \ ProtocolVersion.h \ TrafficMode.h \ + Uri.cc \ + Uri.h \ UriScheme.cc \ UriScheme.h diff -u -r -N squid-4.0.25/src/anyp/Makefile.in squid-4.1/src/anyp/Makefile.in --- squid-4.0.25/src/anyp/Makefile.in 2018-06-12 04:48:00.000000000 +1200 +++ squid-4.1/src/anyp/Makefile.in 2018-07-02 15:32:03.000000000 +1200 @@ -163,7 +163,7 @@ CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libanyp_la_LIBADD = -am_libanyp_la_OBJECTS = PortCfg.lo ProtocolType.lo UriScheme.lo +am_libanyp_la_OBJECTS = PortCfg.lo ProtocolType.lo Uri.lo UriScheme.lo libanyp_la_OBJECTS = $(am_libanyp_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -724,6 +724,8 @@ ProtocolType.h \ ProtocolVersion.h \ TrafficMode.h \ + Uri.cc \ + Uri.h \ UriScheme.cc \ UriScheme.h @@ -793,6 +795,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PortCfg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ProtocolType.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Uri.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UriScheme.Plo@am__quote@ .cc.o: diff -u -r -N squid-4.0.25/src/anyp/Uri.cc squid-4.1/src/anyp/Uri.cc --- squid-4.0.25/src/anyp/Uri.cc 1970-01-01 12:00:00.000000000 +1200 +++ squid-4.1/src/anyp/Uri.cc 2018-07-02 15:26:07.000000000 +1200 @@ -0,0 +1,938 @@ +/* + * Copyright (C) 1996-2018 The Squid Software Foundation and contributors + * + * Squid software is distributed under GPLv2+ license and includes + * contributions from numerous individuals and organizations. + * Please see the COPYING and CONTRIBUTORS files for details. + */ + +/* DEBUG: section 23 URL Parsing */ + +#include "squid.h" +#include "anyp/Uri.h" +#include "globals.h" +#include "HttpRequest.h" +#include "rfc1738.h" +#include "SquidConfig.h" +#include "SquidString.h" + +static const char valid_hostname_chars_u[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789-._" + "[:]" + ; +static const char valid_hostname_chars[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789-." + "[:]" + ; + +const SBuf & +AnyP::Uri::Asterisk() +{ + static SBuf star("*"); + return star; +} + +const SBuf & +AnyP::Uri::SlashPath() +{ + static SBuf slash("/"); + return slash; +} + +void +AnyP::Uri::host(const char *src) +{ + hostAddr_.setEmpty(); + hostAddr_ = src; + if (hostAddr_.isAnyAddr()) { + xstrncpy(host_, src, sizeof(host_)); + hostIsNumeric_ = false; + } else { + hostAddr_.toHostStr(host_, sizeof(host_)); + debugs(23, 3, "given IP: " << hostAddr_); + hostIsNumeric_ = 1; + } + touch(); +} + +const SBuf & +AnyP::Uri::path() const +{ + // RFC 3986 section 3.3 says path can be empty (path-abempty). + // RFC 7230 sections 2.7.3, 5.3.1, 5.7.2 - says path cannot be empty, default to "/" + // at least when sending and using. We must still accept path-abempty as input. + if (path_.isEmpty() && (scheme_ == AnyP::PROTO_HTTP || scheme_ == AnyP::PROTO_HTTPS)) + return SlashPath(); + + return path_; +} + +void +urlInitialize(void) +{ + debugs(23, 5, "urlInitialize: Initializing..."); + /* this ensures that the number of protocol strings is the same as + * the enum slots allocated because the last enum is always 'MAX'. + */ + assert(strcmp(AnyP::ProtocolType_str[AnyP::PROTO_MAX], "MAX") == 0); + /* + * These test that our matchDomainName() function works the + * way we expect it to. + */ + assert(0 == matchDomainName("foo.com", "foo.com")); + assert(0 == matchDomainName(".foo.com", "foo.com")); + assert(0 == matchDomainName("foo.com", ".foo.com")); + assert(0 == matchDomainName(".foo.com", ".foo.com")); + assert(0 == matchDomainName("x.foo.com", ".foo.com")); + assert(0 == matchDomainName("y.x.foo.com", ".foo.com")); + assert(0 != matchDomainName("x.foo.com", "foo.com")); + assert(0 != matchDomainName("foo.com", "x.foo.com")); + assert(0 != matchDomainName("bar.com", "foo.com")); + assert(0 != matchDomainName(".bar.com", "foo.com")); + assert(0 != matchDomainName(".bar.com", ".foo.com")); + assert(0 != matchDomainName("bar.com", ".foo.com")); + assert(0 < matchDomainName("zzz.com", "foo.com")); + assert(0 > matchDomainName("aaa.com", "foo.com")); + assert(0 == matchDomainName("FOO.com", "foo.COM")); + assert(0 < matchDomainName("bfoo.com", "afoo.com")); + assert(0 > matchDomainName("afoo.com", "bfoo.com")); + assert(0 < matchDomainName("x-foo.com", ".foo.com")); + + assert(0 == matchDomainName(".foo.com", ".foo.com", mdnRejectSubsubDomains)); + assert(0 == matchDomainName("x.foo.com", ".foo.com", mdnRejectSubsubDomains)); + assert(0 != matchDomainName("y.x.foo.com", ".foo.com", mdnRejectSubsubDomains)); + assert(0 != matchDomainName(".x.foo.com", ".foo.com", mdnRejectSubsubDomains)); + + assert(0 == matchDomainName("*.foo.com", "x.foo.com", mdnHonorWildcards)); + assert(0 == matchDomainName("*.foo.com", ".x.foo.com", mdnHonorWildcards)); + assert(0 == matchDomainName("*.foo.com", ".foo.com", mdnHonorWildcards)); + assert(0 != matchDomainName("*.foo.com", "foo.com", mdnHonorWildcards)); + + /* more cases? */ +} + +/** + * Parse the scheme name from string b, into protocol type. + * The string must be 0-terminated. + */ +AnyP::ProtocolType +urlParseProtocol(const char *b) +{ + // make e point to the ':' character + const char *e = b + strcspn(b, ":"); + int len = e - b; + + /* test common stuff first */ + + if (strncasecmp(b, "http", len) == 0) + return AnyP::PROTO_HTTP; + + if (strncasecmp(b, "ftp", len) == 0) + return AnyP::PROTO_FTP; + + if (strncasecmp(b, "https", len) == 0) + return AnyP::PROTO_HTTPS; + + if (strncasecmp(b, "file", len) == 0) + return AnyP::PROTO_FTP; + + if (strncasecmp(b, "coap", len) == 0) + return AnyP::PROTO_COAP; + + if (strncasecmp(b, "coaps", len) == 0) + return AnyP::PROTO_COAPS; + + if (strncasecmp(b, "gopher", len) == 0) + return AnyP::PROTO_GOPHER; + + if (strncasecmp(b, "wais", len) == 0) + return AnyP::PROTO_WAIS; + + if (strncasecmp(b, "cache_object", len) == 0) + return AnyP::PROTO_CACHE_OBJECT; + + if (strncasecmp(b, "urn", len) == 0) + return AnyP::PROTO_URN; + + if (strncasecmp(b, "whois", len) == 0) + return AnyP::PROTO_WHOIS; + + if (len > 0) + return AnyP::PROTO_UNKNOWN; + + return AnyP::PROTO_NONE; +} + +/* + * Parse a URI/URL. + * + * Stores parsed values in the `request` argument. + * + * This abuses HttpRequest as a way of representing the parsed url + * and its components. + * method is used to switch parsers and to init the HttpRequest. + * If method is Http::METHOD_CONNECT, then rather than a URL a hostname:port is + * looked for. + * The url is non const so that if its too long we can NULL-terminate it in place. + */ + +/* + * This routine parses a URL. Its assumed that the URL is complete - + * ie, the end of the string is the end of the URL. Don't pass a partial + * URL here as this routine doesn't have any way of knowing whether + * its partial or not (ie, it handles the case of no trailing slash as + * being "end of host with implied path of /". + */ +bool +AnyP::Uri::parse(const HttpRequestMethod& method, const char *url) +{ + LOCAL_ARRAY(char, proto, MAX_URL); + LOCAL_ARRAY(char, login, MAX_URL); + LOCAL_ARRAY(char, foundHost, MAX_URL); + LOCAL_ARRAY(char, urlpath, MAX_URL); + char *t = NULL; + char *q = NULL; + int foundPort; + AnyP::ProtocolType protocol = AnyP::PROTO_NONE; + int l; + int i; + const char *src; + char *dst; + proto[0] = foundHost[0] = urlpath[0] = login[0] = '\0'; + + if ((l = strlen(url)) + Config.appendDomainLen > (MAX_URL - 1)) { + debugs(23, DBG_IMPORTANT, MYNAME << "URL too large (" << l << " bytes)"); + return false; + } + if (method == Http::METHOD_CONNECT) { + /* + * RFC 7230 section 5.3.3: authority-form = authority + * "excluding any userinfo and its "@" delimiter" + * + * RFC 3986 section 3.2: authority = [ userinfo "@" ] host [ ":" port ] + * + * As an HTTP(S) proxy we assume HTTPS (443) if no port provided. + */ + foundPort = 443; + + if (sscanf(url, "[%[^]]]:%d", foundHost, &foundPort) < 1) + if (sscanf(url, "%[^:]:%d", foundHost, &foundPort) < 1) + return false; + + } else if ((method == Http::METHOD_OPTIONS || method == Http::METHOD_TRACE) && + AnyP::Uri::Asterisk().cmp(url) == 0) { + parseFinish(AnyP::PROTO_HTTP, nullptr, url, foundHost, SBuf(), 80 /* HTTP default port */); + return true; + } else if (strncmp(url, "urn:", 4) == 0) { + debugs(23, 3, "Split URI '" << url << "' into proto='urn', path='" << (url+4) << "'"); + debugs(50, 5, "urn=" << (url+4)); + setScheme(AnyP::PROTO_URN, nullptr); + path(url + 4); + return true; + } else { + /* Parse the URL: */ + src = url; + i = 0; + /* Find first : - everything before is protocol */ + for (i = 0, dst = proto; i < l && *src != ':'; ++i, ++src, ++dst) { + *dst = *src; + } + if (i >= l) + return false; + *dst = '\0'; + + /* Then its :// */ + if ((i+3) > l || *src != ':' || *(src + 1) != '/' || *(src + 2) != '/') + return false; + i += 3; + src += 3; + + /* Then everything until first /; thats host (and port; which we'll look for here later) */ + // bug 1881: If we don't get a "/" then we imply it was there + // bug 3074: We could just be given a "?" or "#". These also imply "/" + // bug 3233: whitespace is also a hostname delimiter. + for (dst = foundHost; i < l && *src != '/' && *src != '?' && *src != '#' && *src != '\0' && !xisspace(*src); ++i, ++src, ++dst) { + *dst = *src; + } + + /* + * We can't check for "i >= l" here because we could be at the end of the line + * and have a perfectly valid URL w/ no trailing '/'. In this case we assume we've + * been -given- a valid URL and the path is just '/'. + */ + if (i > l) + return false; + *dst = '\0'; + + // bug 3074: received 'path' starting with '?', '#', or '\0' implies '/' + if (*src == '?' || *src == '#' || *src == '\0') { + urlpath[0] = '/'; + dst = &urlpath[1]; + } else { + dst = urlpath; + } + /* Then everything from / (inclusive) until \r\n or \0 - thats urlpath */ + for (; i < l && *src != '\r' && *src != '\n' && *src != '\0'; ++i, ++src, ++dst) { + *dst = *src; + } + + /* We -could- be at the end of the buffer here */ + if (i > l) + return false; + /* If the URL path is empty we set it to be "/" */ + if (dst == urlpath) { + *dst = '/'; + ++dst; + } + *dst = '\0'; + + protocol = urlParseProtocol(proto); + foundPort = AnyP::UriScheme(protocol).defaultPort(); + + /* Is there any login information? (we should eventually parse it above) */ + t = strrchr(foundHost, '@'); + if (t != NULL) { + strncpy((char *) login, (char *) foundHost, sizeof(login)-1); + login[sizeof(login)-1] = '\0'; + t = strrchr(login, '@'); + *t = 0; + strncpy((char *) foundHost, t + 1, sizeof(foundHost)-1); + foundHost[sizeof(foundHost)-1] = '\0'; + // Bug 4498: URL-unescape the login info after extraction + rfc1738_unescape(login); + } + + /* Is there any host information? (we should eventually parse it above) */ + if (*foundHost == '[') { + /* strip any IPA brackets. valid under IPv6. */ + dst = foundHost; + /* only for IPv6 sadly, pre-IPv6/URL code can't handle the clean result properly anyway. */ + src = foundHost; + ++src; + l = strlen(foundHost); + i = 1; + for (; i < l && *src != ']' && *src != '\0'; ++i, ++src, ++dst) { + *dst = *src; + } + + /* we moved in-place, so truncate the actual hostname found */ + *dst = '\0'; + ++dst; + + /* skip ahead to either start of port, or original EOS */ + while (*dst != '\0' && *dst != ':') + ++dst; + t = dst; + } else { + t = strrchr(foundHost, ':'); + + if (t != strchr(foundHost,':') ) { + /* RFC 2732 states IPv6 "SHOULD" be bracketed. allowing for times when its not. */ + /* RFC 3986 'update' simply modifies this to an "is" with no emphasis at all! */ + /* therefore we MUST accept the case where they are not bracketed at all. */ + t = NULL; + } + } + + // Bug 3183 sanity check: If scheme is present, host must be too. + if (protocol != AnyP::PROTO_NONE && foundHost[0] == '\0') { + debugs(23, DBG_IMPORTANT, "SECURITY ALERT: Missing hostname in URL '" << url << "'. see access.log for details."); + return false; + } + + if (t && *t == ':') { + *t = '\0'; + ++t; + foundPort = atoi(t); + } + } + + for (t = foundHost; *t; ++t) + *t = xtolower(*t); + + if (stringHasWhitespace(foundHost)) { + if (URI_WHITESPACE_STRIP == Config.uri_whitespace) { + t = q = foundHost; + while (*t) { + if (!xisspace(*t)) { + *q = *t; + ++q; + } + ++t; + } + *q = '\0'; + } + } + + debugs(23, 3, "Split URL '" << url << "' into proto='" << proto << "', host='" << foundHost << "', port='" << foundPort << "', path='" << urlpath << "'"); + + if (Config.onoff.check_hostnames && + strspn(foundHost, Config.onoff.allow_underscore ? valid_hostname_chars_u : valid_hostname_chars) != strlen(foundHost)) { + debugs(23, DBG_IMPORTANT, MYNAME << "Illegal character in hostname '" << foundHost << "'"); + return false; + } + + /* For IPV6 addresses also check for a colon */ + if (Config.appendDomain && !strchr(foundHost, '.') && !strchr(foundHost, ':')) + strncat(foundHost, Config.appendDomain, SQUIDHOSTNAMELEN - strlen(foundHost) - 1); + + /* remove trailing dots from hostnames */ + while ((l = strlen(foundHost)) > 0 && foundHost[--l] == '.') + foundHost[l] = '\0'; + + /* reject duplicate or leading dots */ + if (strstr(foundHost, "..") || *foundHost == '.') { + debugs(23, DBG_IMPORTANT, MYNAME << "Illegal hostname '" << foundHost << "'"); + return false; + } + + if (foundPort < 1 || foundPort > 65535) { + debugs(23, 3, "Invalid port '" << foundPort << "'"); + return false; + } + +#if HARDCODE_DENY_PORTS + /* These ports are filtered in the default squid.conf, but + * maybe someone wants them hardcoded... */ + if (foundPort == 7 || foundPort == 9 || foundPort == 19) { + debugs(23, DBG_CRITICAL, MYNAME << "Deny access to port " << foundPort); + return false; + } +#endif + + if (stringHasWhitespace(urlpath)) { + debugs(23, 2, "URI has whitespace: {" << url << "}"); + + switch (Config.uri_whitespace) { + + case URI_WHITESPACE_DENY: + return false; + + case URI_WHITESPACE_ALLOW: + break; + + case URI_WHITESPACE_ENCODE: + t = rfc1738_escape_unescaped(urlpath); + xstrncpy(urlpath, t, MAX_URL); + break; + + case URI_WHITESPACE_CHOP: + *(urlpath + strcspn(urlpath, w_space)) = '\0'; + break; + + case URI_WHITESPACE_STRIP: + default: + t = q = urlpath; + while (*t) { + if (!xisspace(*t)) { + *q = *t; + ++q; + } + ++t; + } + *q = '\0'; + } + } + + parseFinish(protocol, proto, urlpath, foundHost, SBuf(login), foundPort); + return true; +} + +/// Update the URL object with parsed URI data. +void +AnyP::Uri::parseFinish(const AnyP::ProtocolType protocol, + const char *const protoStr, // for unknown protocols + const char *const aUrlPath, + const char *const aHost, + const SBuf &aLogin, + const int aPort) +{ + setScheme(protocol, protoStr); + path(aUrlPath); + host(aHost); + userInfo(aLogin); + port(aPort); +} + +void +AnyP::Uri::touch() +{ + absolute_.clear(); + authorityHttp_.clear(); + authorityWithPort_.clear(); +} + +SBuf & +AnyP::Uri::authority(bool requirePort) const +{ + if (authorityHttp_.isEmpty()) { + + // both formats contain Host/IP + authorityWithPort_.append(host()); + authorityHttp_ = authorityWithPort_; + + // authorityForm_ only has :port if it is non-default + authorityWithPort_.appendf(":%u",port()); + if (port() != getScheme().defaultPort()) + authorityHttp_ = authorityWithPort_; + } + + return requirePort ? authorityWithPort_ : authorityHttp_; +} + +SBuf & +AnyP::Uri::absolute() const +{ + if (absolute_.isEmpty()) { + // TODO: most URL will be much shorter, avoid allocating this much + absolute_.reserveCapacity(MAX_URL); + + absolute_.append(getScheme().image()); + absolute_.append(":",1); + if (getScheme() != AnyP::PROTO_URN) { + absolute_.append("//", 2); + const bool omitUserInfo = getScheme() == AnyP::PROTO_HTTP || + getScheme() != AnyP::PROTO_HTTPS || + userInfo().isEmpty(); + if (!omitUserInfo) { + absolute_.append(userInfo()); + absolute_.append("@", 1); + } + absolute_.append(authority()); + } + absolute_.append(path()); + } + + return absolute_; +} + +/** \todo AYJ: Performance: This is an *almost* duplicate of HttpRequest::effectiveRequestUri(). But elides the query-string. + * After copying it on in the first place! Would be less code to merge the two with a flag parameter. + * and never copy the query-string part in the first place + */ +char * +urlCanonicalClean(const HttpRequest * request) +{ + LOCAL_ARRAY(char, buf, MAX_URL); + + snprintf(buf, sizeof(buf), SQUIDSBUFPH, SQUIDSBUFPRINT(request->effectiveRequestUri())); + buf[sizeof(buf)-1] = '\0'; + + // URN, CONNECT method, and non-stripped URIs can go straight out + if (Config.onoff.strip_query_terms && !(request->method == Http::METHOD_CONNECT || request->url.getScheme() == AnyP::PROTO_URN)) { + // strip anything AFTER a question-mark + // leaving the '?' in place + if (auto t = strchr(buf, '?')) { + *(++t) = '\0'; + } + } + + if (stringHasCntl(buf)) + xstrncpy(buf, rfc1738_escape_unescaped(buf), MAX_URL); + + return buf; +} + +/** + * Yet another alternative to urlCanonical. + * This one adds the https:// parts to Http::METHOD_CONNECT URL + * for use in error page outputs. + * Luckily we can leverage the others instead of duplicating. + */ +const char * +urlCanonicalFakeHttps(const HttpRequest * request) +{ + LOCAL_ARRAY(char, buf, MAX_URL); + + // method CONNECT and port HTTPS + if (request->method == Http::METHOD_CONNECT && request->url.port() == 443) { + snprintf(buf, MAX_URL, "https://%s/*", request->url.host()); + return buf; + } + + // else do the normal complete canonical thing. + return urlCanonicalClean(request); +} + +/* + * Test if a URL is relative. + * + * RFC 2396, Section 5 (Page 17) implies that in a relative URL, a '/' will + * appear before a ':'. + */ +bool +urlIsRelative(const char *url) +{ + const char *p; + + if (url == NULL) { + return (false); + } + if (*url == '\0') { + return (false); + } + + for (p = url; *p != '\0' && *p != ':' && *p != '/'; ++p); + + if (*p == ':') { + return (false); + } + return (true); +} + +/* + * Convert a relative URL to an absolute URL using the context of a given + * request. + * + * It is assumed that you have already ensured that the URL is relative. + * + * If NULL is returned it is an indication that the method in use in the + * request does not distinguish between relative and absolute and you should + * use the url unchanged. + * + * If non-NULL is returned, it is up to the caller to free the resulting + * memory using safe_free(). + */ +char * +urlMakeAbsolute(const HttpRequest * req, const char *relUrl) +{ + + if (req->method.id() == Http::METHOD_CONNECT) { + return (NULL); + } + + char *urlbuf = (char *)xmalloc(MAX_URL * sizeof(char)); + + if (req->url.getScheme() == AnyP::PROTO_URN) { + // XXX: this is what the original code did, but it seems to break the + // intended behaviour of this function. It returns the stored URN path, + // not converting the given one into a URN... + snprintf(urlbuf, MAX_URL, SQUIDSBUFPH, SQUIDSBUFPRINT(req->url.absolute())); + return (urlbuf); + } + + SBuf authorityForm = req->url.authority(); // host[:port] + const SBuf &scheme = req->url.getScheme().image(); + size_t urllen = snprintf(urlbuf, MAX_URL, SQUIDSBUFPH "://" SQUIDSBUFPH "%s" SQUIDSBUFPH, + SQUIDSBUFPRINT(scheme), + SQUIDSBUFPRINT(req->url.userInfo()), + !req->url.userInfo().isEmpty() ? "@" : "", + SQUIDSBUFPRINT(authorityForm)); + + // if the first char is '/' assume its a relative path + // XXX: this breaks on scheme-relative URLs, + // but we should not see those outside ESI, and rarely there. + // XXX: also breaks on any URL containing a '/' in the query-string portion + if (relUrl[0] == '/') { + xstrncpy(&urlbuf[urllen], relUrl, MAX_URL - urllen - 1); + } else { + SBuf path = req->url.path(); + SBuf::size_type lastSlashPos = path.rfind('/'); + + if (lastSlashPos == SBuf::npos) { + // replace the whole path with the given bit(s) + urlbuf[urllen] = '/'; + ++urllen; + xstrncpy(&urlbuf[urllen], relUrl, MAX_URL - urllen - 1); + } else { + // replace only the last (file?) segment with the given bit(s) + ++lastSlashPos; + if (lastSlashPos > MAX_URL - urllen - 1) { + // XXX: crops bits in the middle of the combined URL. + lastSlashPos = MAX_URL - urllen - 1; + } + SBufToCstring(&urlbuf[urllen], path.substr(0,lastSlashPos)); + urllen += lastSlashPos; + if (urllen + 1 < MAX_URL) { + xstrncpy(&urlbuf[urllen], relUrl, MAX_URL - urllen - 1); + } + } + } + + return (urlbuf); +} + +int +matchDomainName(const char *h, const char *d, uint flags) +{ + int dl; + int hl; + + const bool hostIncludesSubdomains = (*h == '.'); + while ('.' == *h) + ++h; + + hl = strlen(h); + + if (hl == 0) + return -1; + + dl = strlen(d); + + /* + * Start at the ends of the two strings and work towards the + * beginning. + */ + while (xtolower(h[--hl]) == xtolower(d[--dl])) { + if (hl == 0 && dl == 0) { + /* + * We made it all the way to the beginning of both + * strings without finding any difference. + */ + return 0; + } + + if (0 == hl) { + /* + * The host string is shorter than the domain string. + * There is only one case when this can be a match. + * If the domain is just one character longer, and if + * that character is a leading '.' then we call it a + * match. + */ + + if (1 == dl && '.' == d[0]) + return 0; + else + return -1; + } + + if (0 == dl) { + /* + * The domain string is shorter than the host string. + * This is a match only if the first domain character + * is a leading '.'. + */ + + if ('.' == d[0]) { + if (flags & mdnRejectSubsubDomains) { + // Check for sub-sub domain and reject + while(--hl >= 0 && h[hl] != '.'); + if (hl < 0) { + // No sub-sub domain found, but reject if there is a + // leading dot in given host string (which is removed + // before the check is started). + return hostIncludesSubdomains ? 1 : 0; + } else + return 1; // sub-sub domain, reject + } else + return 0; + } else + return 1; + } + } + + /* + * We found different characters in the same position (from the end). + */ + + // If the h has a form of "*.foo.com" and d has a form of "x.foo.com" + // then the h[hl] points to '*', h[hl+1] to '.' and d[dl] to 'x' + // The following checks are safe, the "h[hl + 1]" in the worst case is '\0'. + if ((flags & mdnHonorWildcards) && h[hl] == '*' && h[hl + 1] == '.') + return 0; + + /* + * If one of those character is '.' then its special. In order + * for splay tree sorting to work properly, "x-foo.com" must + * be greater than ".foo.com" even though '-' is less than '.'. + */ + if ('.' == d[dl]) + return 1; + + if ('.' == h[hl]) + return -1; + + return (xtolower(h[hl]) - xtolower(d[dl])); +} + +/* + * return true if we can serve requests for this method. + */ +int +urlCheckRequest(const HttpRequest * r) +{ + int rc = 0; + /* protocol "independent" methods + * + * actually these methods are specific to HTTP: + * they are methods we recieve on our HTTP port, + * and if we had a FTP listener would not be relevant + * there. + * + * So, we should delegate them to HTTP. The problem is that we + * do not have a default protocol from the client side of HTTP. + */ + + if (r->method == Http::METHOD_CONNECT) + return 1; + + // we support OPTIONS and TRACE directed at us (with a 501 reply, for now) + // we also support forwarding OPTIONS and TRACE, except for the *-URI ones + if (r->method == Http::METHOD_OPTIONS || r->method == Http::METHOD_TRACE) + return (r->header.getInt64(Http::HdrType::MAX_FORWARDS) == 0 || r->url.path() != AnyP::Uri::Asterisk()); + + if (r->method == Http::METHOD_PURGE) + return 1; + + /* does method match the protocol? */ + switch (r->url.getScheme()) { + + case AnyP::PROTO_URN: + + case AnyP::PROTO_HTTP: + + case AnyP::PROTO_CACHE_OBJECT: + rc = 1; + break; + + case AnyP::PROTO_FTP: + + if (r->method == Http::METHOD_PUT) + rc = 1; + + case AnyP::PROTO_GOPHER: + + case AnyP::PROTO_WAIS: + + case AnyP::PROTO_WHOIS: + if (r->method == Http::METHOD_GET) + rc = 1; + else if (r->method == Http::METHOD_HEAD) + rc = 1; + + break; + + case AnyP::PROTO_HTTPS: +#if USE_OPENSSL + rc = 1; +#elif USE_GNUTLS + rc = 1; +#else + /* + * Squid can't originate an SSL connection, so it should + * never receive an "https:" URL. It should always be + * CONNECT instead. + */ + rc = 0; +#endif + break; + + default: + break; + } + + return rc; +} + +/* + * Quick-n-dirty host extraction from a URL. Steps: + * Look for a colon + * Skip any '/' after the colon + * Copy the next SQUID_MAXHOSTNAMELEN bytes to host[] + * Look for an ending '/' or ':' and terminate + * Look for login info preceeded by '@' + */ + +class URLHostName +{ + +public: + char * extract(char const *url); + +private: + static char Host [SQUIDHOSTNAMELEN]; + void init(char const *); + void findHostStart(); + void trimTrailingChars(); + void trimAuth(); + char const *hostStart; + char const *url; +}; + +char * +urlHostname(const char *url) +{ + return URLHostName().extract(url); +} + +char URLHostName::Host[SQUIDHOSTNAMELEN]; + +void +URLHostName::init(char const *aUrl) +{ + Host[0] = '\0'; + url = aUrl; +} + +void +URLHostName::findHostStart() +{ + if (NULL == (hostStart = strchr(url, ':'))) + return; + + ++hostStart; + + while (*hostStart != '\0' && *hostStart == '/') + ++hostStart; + + if (*hostStart == ']') + ++hostStart; +} + +void +URLHostName::trimTrailingChars() +{ + char *t; + + if ((t = strchr(Host, '/'))) + *t = '\0'; + + if ((t = strrchr(Host, ':'))) + *t = '\0'; + + if ((t = strchr(Host, ']'))) + *t = '\0'; +} + +void +URLHostName::trimAuth() +{ + char *t; + + if ((t = strrchr(Host, '@'))) { + ++t; + memmove(Host, t, strlen(t) + 1); + } +} + +char * +URLHostName::extract(char const *aUrl) +{ + init(aUrl); + findHostStart(); + + if (hostStart == NULL) + return NULL; + + xstrncpy(Host, hostStart, SQUIDHOSTNAMELEN); + + trimTrailingChars(); + + trimAuth(); + + return Host; +} + +AnyP::Uri::Uri(AnyP::UriScheme const &aScheme) : + scheme_(aScheme), + hostIsNumeric_(false), + port_(0) +{ + *host_=0; +} + diff -u -r -N squid-4.0.25/src/anyp/Uri.h squid-4.1/src/anyp/Uri.h --- squid-4.0.25/src/anyp/Uri.h 1970-01-01 12:00:00.000000000 +1200 +++ squid-4.1/src/anyp/Uri.h 2018-07-02 15:26:07.000000000 +1200 @@ -0,0 +1,234 @@ +/* + * Copyright (C) 1996-2018 The Squid Software Foundation and contributors + * + * Squid software is distributed under GPLv2+ license and includes + * contributions from numerous individuals and organizations. + * Please see the COPYING and CONTRIBUTORS files for details. + */ + +#ifndef SQUID_SRC_ANYP_URI_H +#define SQUID_SRC_ANYP_URI_H + +#include "anyp/UriScheme.h" +#include "ip/Address.h" +#include "rfc2181.h" +#include "sbuf/SBuf.h" + +#include + +class HttpRequestMethod; + +namespace AnyP +{ + +/** + * Represents a Uniform Resource Identifier. + * Can store both URL or URN representations. + * + * Governed by RFC 3986 + */ +class Uri +{ + MEMPROXY_CLASS(Uri); + +public: + Uri() : hostIsNumeric_(false), port_(0) {*host_=0;} + Uri(AnyP::UriScheme const &aScheme); + Uri(const Uri &other) { + this->operator =(other); + } + Uri &operator =(const Uri &o) { + scheme_ = o.scheme_; + userInfo_ = o.userInfo_; + memcpy(host_, o.host_, sizeof(host_)); + hostIsNumeric_ = o.hostIsNumeric_; + hostAddr_ = o.hostAddr_; + port_ = o.port_; + path_ = o.path_; + touch(); + return *this; + } + + void clear() { + scheme_=AnyP::PROTO_NONE; + hostIsNumeric_ = false; + *host_ = 0; + hostAddr_.setEmpty(); + port_ = 0; + touch(); + } + void touch(); ///< clear the cached URI display forms + + bool parse(const HttpRequestMethod &, const char *url); + + AnyP::UriScheme const & getScheme() const {return scheme_;} + + /// convert the URL scheme to that given + void setScheme(const AnyP::ProtocolType &p, const char *str) { + scheme_ = AnyP::UriScheme(p, str); + touch(); + } + + void userInfo(const SBuf &s) {userInfo_=s; touch();} + const SBuf &userInfo() const {return userInfo_;} + + void host(const char *src); + const char *host(void) const {return host_;} + int hostIsNumeric(void) const {return hostIsNumeric_;} + Ip::Address const & hostIP(void) const {return hostAddr_;} + + void port(unsigned short p) {port_=p; touch();} + unsigned short port() const {return port_;} + + void path(const char *p) {path_=p; touch();} + void path(const SBuf &p) {path_=p; touch();} + const SBuf &path() const; + + /// the static '/' default URL-path + static const SBuf &SlashPath(); + + /// the static '*' pseudo-URI + static const SBuf &Asterisk(); + + /** + * The authority-form URI for currently stored values. + * + * As defined by RFC 7230 section 5.3.3 this form omits the + * userinfo@ field from RFC 3986 defined authority segment. + * + * \param requirePort when true the port will be included, otherwise + * port will be elided when it is the default for + * the current scheme. + */ + SBuf &authority(bool requirePort = false) const; + + /** + * The absolute-form URI for currently stored values. + * + * As defined by RFC 7230 section 5.3.3 this form omits the + * userinfo@ field from RFC 3986 defined authority segments + * when the protocol scheme is http: or https:. + */ + SBuf &absolute() const; + +private: + void parseFinish(const AnyP::ProtocolType, const char *const, const char *const, const char *const, const SBuf &, const int); + + /** + \par + * The scheme of this URL. This has the 'type code' smell about it. + * In future we may want to make the methods that dispatch based on + * the scheme virtual and have a class per protocol. + \par + * On the other hand, having Protocol as an explicit concept is useful, + * see for instance the ACLProtocol acl type. One way to represent this + * is to have one prototype URL with no host etc for each scheme, + * another is to have an explicit scheme class, and then each URL class + * could be a subclass of the scheme. Another way is one instance of + * a AnyP::UriScheme class instance for each URL scheme we support, and one + * class for each manner of treating the scheme : a Hierarchical URL, a + * non-hierarchical URL etc. + \par + * Deferring the decision, its a type code for now. RBC 20060507. + \par + * In order to make taking any of these routes easy, scheme is private, + * only settable at construction time, or with explicit setter + */ + AnyP::UriScheme scheme_; + + SBuf userInfo_; // aka 'URL-login' + + // XXX: uses char[] instead of SBUf to reduce performance regressions + // from c_str() since most code using this is not yet using SBuf + char host_[SQUIDHOSTNAMELEN]; ///< string representation of the URI authority name or IP + bool hostIsNumeric_; ///< whether the authority 'host' is a raw-IP + Ip::Address hostAddr_; ///< binary representation of the URI authority if it is a raw-IP + + unsigned short port_; ///< URL port + + // XXX: for now includes query-string. + SBuf path_; ///< URI path segment + + // pre-assembled URI forms + mutable SBuf authorityHttp_; ///< RFC 7230 section 5.3.3 authority, maybe without default-port + mutable SBuf authorityWithPort_; ///< RFC 7230 section 5.3.3 authority with explicit port + mutable SBuf absolute_; ///< RFC 7230 section 5.3.2 absolute-URI +}; + +} // namespace AnyP + +inline std::ostream & +operator <<(std::ostream &os, const AnyP::Uri &url) +{ + // none means explicit empty string for scheme. + if (url.getScheme() != AnyP::PROTO_NONE) + os << url.getScheme().image(); + os << ":"; + + // no authority section on URN + if (url.getScheme() != AnyP::PROTO_URN) + os << "//" << url.authority(); + + // path is what it is - including absent + os << url.path(); + return os; +} + +/* Deprecated functions for Legacy code handling URLs */ + +class HttpRequest; + +void urlInitialize(void); +char *urlCanonicalClean(const HttpRequest *); +const char *urlCanonicalFakeHttps(const HttpRequest * request); +bool urlIsRelative(const char *); +char *urlMakeAbsolute(const HttpRequest *, const char *); +char *urlRInternal(const char *host, unsigned short port, const char *dir, const char *name); +char *urlInternal(const char *dir, const char *name); + +enum MatchDomainNameFlags { + mdnNone = 0, + mdnHonorWildcards = 1 << 0, + mdnRejectSubsubDomains = 1 << 1 +}; + +/** + * matchDomainName() matches a hostname (usually extracted from traffic) + * with a domainname when mdnNone or mdnRejectSubsubDomains flags are used + * according to the following rules: + * + * HOST | DOMAIN | mdnNone | mdnRejectSubsubDomains + * -------------|-------------|-----------|----------------------- + * foo.com | foo.com | YES | YES + * .foo.com | foo.com | YES | YES + * x.foo.com | foo.com | NO | NO + * foo.com | .foo.com | YES | YES + * .foo.com | .foo.com | YES | YES + * x.foo.com | .foo.com | YES | YES + * .x.foo.com | .foo.com | YES | NO + * y.x.foo.com | .foo.com | YES | NO + * + * if mdnHonorWildcards flag is set then the matchDomainName() also accepts + * optional wildcards on hostname: + * + * HOST | DOMAIN | MATCH? + * -------------|--------------|------- + * *.foo.com | x.foo.com | YES + * *.foo.com | .x.foo.com | YES + * *.foo.com | .foo.com | YES + * *.foo.com | foo.com | NO + * + * The combination of mdnHonorWildcards and mdnRejectSubsubDomains flags is + * supported. + * + * \retval 0 means the host matches the domain + * \retval 1 means the host is greater than the domain + * \retval -1 means the host is less than the domain + */ +int matchDomainName(const char *host, const char *domain, uint flags = mdnNone); +int urlCheckRequest(const HttpRequest *); +char *urlHostname(const char *url); +void urlExtMethodConfigure(void); + +#endif /* SQUID_SRC_ANYP_URI_H */ + diff -u -r -N squid-4.0.25/src/auth/basic/DB/basic_db_auth.8 squid-4.1/src/auth/basic/DB/basic_db_auth.8 --- squid-4.0.25/src/auth/basic/DB/basic_db_auth.8 2018-06-12 04:56:19.000000000 +1200 +++ squid-4.1/src/auth/basic/DB/basic_db_auth.8 2018-07-02 15:39:07.000000000 +1200 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BASIC_DB_AUTH 8" -.TH BASIC_DB_AUTH 8 "2018-06-11" "perl v5.26.2" "User Contributed Perl Documentation" +.TH BASIC_DB_AUTH 8 "2018-07-02" "perl v5.26.2" "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-4.0.25/src/auth/basic/POP3/basic_pop3_auth.8 squid-4.1/src/auth/basic/POP3/basic_pop3_auth.8 --- squid-4.0.25/src/auth/basic/POP3/basic_pop3_auth.8 2018-06-12 04:56:20.000000000 +1200 +++ squid-4.1/src/auth/basic/POP3/basic_pop3_auth.8 2018-07-02 15:39:07.000000000 +1200 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BASIC_POP3_AUTH 8" -.TH BASIC_POP3_AUTH 8 "2018-06-11" "perl v5.26.2" "User Contributed Perl Documentation" +.TH BASIC_POP3_AUTH 8 "2018-07-02" "perl v5.26.2" "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-4.0.25/src/carp.cc squid-4.1/src/carp.cc --- squid-4.0.25/src/carp.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/carp.cc 2018-07-02 15:26:07.000000000 +1200 @@ -15,7 +15,6 @@ #include "neighbors.h" #include "SquidConfig.h" #include "Store.h" -#include "URL.h" #include diff -u -r -N squid-4.0.25/src/clients/Client.cc squid-4.1/src/clients/Client.cc --- squid-4.0.25/src/clients/Client.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/clients/Client.cc 2018-07-02 15:26:07.000000000 +1200 @@ -25,7 +25,6 @@ #include "StatCounters.h" #include "Store.h" #include "tools.h" -#include "URL.h" #if USE_ADAPTATION #include "adaptation/AccessCheck.h" diff -u -r -N squid-4.0.25/src/clients/FtpGateway.cc squid-4.1/src/clients/FtpGateway.cc --- squid-4.0.25/src/clients/FtpGateway.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/clients/FtpGateway.cc 2018-07-02 15:26:07.000000000 +1200 @@ -38,7 +38,6 @@ #include "StatCounters.h" #include "Store.h" #include "tools.h" -#include "URL.h" #include "util.h" #include "wordlist.h" @@ -2289,8 +2288,7 @@ ferr.ftp.cwd_msg = xstrdup(cwd_message.size()? cwd_message.termedBuf() : ""); ferr.ftp.server_msg = ctrl.message; ctrl.message = NULL; - entry->replaceHttpReply( ferr.BuildHttpReply() ); - EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT); + entry->replaceHttpReply(ferr.BuildHttpReply()); entry->flush(); entry->unlock("Ftp::Gateway"); } @@ -2563,8 +2561,6 @@ assert(entry->isEmpty()); - EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT); - entry->buffer(); /* released when done processing current data payload */ SBuf urlPath = request->url.path(); diff -u -r -N squid-4.0.25/src/clients/FtpRelay.cc squid-4.1/src/clients/FtpRelay.cc --- squid-4.0.25/src/clients/FtpRelay.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/clients/FtpRelay.cc 2018-07-02 15:26:07.000000000 +1200 @@ -292,7 +292,6 @@ const Http::StatusCode httpStatus = failedHttpStatus(error); HttpReply *const reply = createHttpReply(httpStatus); entry->replaceHttpReply(reply); - EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT); fwd->request->detailError(error, xerrno); } @@ -375,7 +374,6 @@ Ftp::Relay::forwardReply() { assert(entry->isEmpty()); - EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT); HttpReply *const reply = createHttpReply(Http::scNoContent); reply->sources |= HttpMsg::srcFtp; @@ -453,7 +451,6 @@ HttpReply *const reply = createHttpReply(Http::scOkay, -1); reply->sources |= HttpMsg::srcFtp; - EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT); setVirginReply(reply); adaptOrFinalizeReply(); diff -u -r -N squid-4.0.25/src/client_side.cc squid-4.1/src/client_side.cc --- squid-4.0.25/src/client_side.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/client_side.cc 2018-07-02 15:26:07.000000000 +1200 @@ -113,7 +113,6 @@ #include "Store.h" #include "TimeOrTag.h" #include "tools.h" -#include "URL.h" #if USE_AUTH #include "auth/UserRequest.h" diff -u -r -N squid-4.0.25/src/client_side_reply.cc squid-4.1/src/client_side_reply.cc --- squid-4.0.25/src/client_side_reply.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/client_side_reply.cc 2018-07-02 15:26:07.000000000 +1200 @@ -37,7 +37,6 @@ #include "Store.h" #include "StrList.h" #include "tools.h" -#include "URL.h" #if USE_AUTH #include "auth/UserRequest.h" #endif diff -u -r -N squid-4.0.25/src/client_side_request.cc squid-4.1/src/client_side_request.cc --- squid-4.0.25/src/client_side_request.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/client_side_request.cc 2018-07-02 15:26:07.000000000 +1200 @@ -53,7 +53,6 @@ #include "Store.h" #include "StrList.h" #include "tools.h" -#include "URL.h" #include "wordlist.h" #if USE_AUTH #include "auth/UserRequest.h" @@ -1264,7 +1263,7 @@ // prevent broken helpers causing too much damage. If old URL == new URL skip the re-write. if (urlNote != NULL && strcmp(urlNote, http->uri)) { - URL tmpUrl; + AnyP::Uri tmpUrl; if (tmpUrl.parse(old_request->method, urlNote)) { HttpRequest *new_request = old_request->clone(); new_request->url = tmpUrl; @@ -1953,7 +1952,6 @@ assert(repContext); repContext->createStoreEntry(request->method, request->flags); - EBIT_CLR(storeEntry()->flags, ENTRY_FWD_HDR_WAIT); request_satisfaction_mode = true; request_satisfaction_offset = 0; storeEntry()->replaceHttpReply(new_rep); diff -u -r -N squid-4.0.25/src/enums.h squid-4.1/src/enums.h --- squid-4.0.25/src/enums.h 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/enums.h 2018-07-02 15:26:07.000000000 +1200 @@ -75,12 +75,31 @@ enum { ENTRY_SPECIAL, ENTRY_REVALIDATE_ALWAYS, + + /// Tiny Store writes are likely. The writes should be aggregated together + /// before Squid announces the new content availability to the store + /// clients. For example, forming a cached HTTP response header may result + /// in dozens of StoreEntry::write() calls, many of which adding as little + /// as two bytes. Sharing those small writes with the store clients + /// increases overhead, especially because the client code can do nothing + /// useful with the written content until the whole response header is + /// stored. Might be combined with ENTRY_FWD_HDR_WAIT. TODO: Rename to + /// ENTRY_DELAY_WHILE_COALESCING to emphasize the difference from and + /// similarity with ENTRY_FWD_HDR_WAIT. DELAY_SENDING, RELEASE_REQUEST, ///< prohibits making the key public REFRESH_REQUEST, ENTRY_REVALIDATE_STALE, ENTRY_DISPATCHED, KEY_PRIVATE, + + /// The current entry response may change. The contents of an entry in this + /// state must not be shared with its store clients. For example, Squid + /// receives (and buffers) an HTTP/504 response but may decide to retry that + /// transaction to receive a successful response from another server + /// instead. Might be combined with DELAY_SENDING. TODO: Rename to + /// ENTRY_DELAY_WHILE_WOBBLING to emphasize the difference from and + /// similarity with DELAY_SENDING. ENTRY_FWD_HDR_WAIT, ENTRY_NEGCACHED, ENTRY_VALIDATED, diff -u -r -N squid-4.0.25/src/errorpage.cc squid-4.1/src/errorpage.cc --- squid-4.0.25/src/errorpage.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/errorpage.cc 2018-07-02 15:26:07.000000000 +1200 @@ -27,7 +27,6 @@ #include "SquidConfig.h" #include "Store.h" #include "tools.h" -#include "URL.h" #include "wordlist.h" #if USE_AUTH #include "auth/UserRequest.h" diff -u -r -N squid-4.0.25/src/external_acl.cc squid-4.1/src/external_acl.cc --- squid-4.0.25/src/external_acl.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/external_acl.cc 2018-07-02 15:26:07.000000000 +1200 @@ -35,7 +35,6 @@ #include "SquidTime.h" #include "Store.h" #include "tools.h" -#include "URL.h" #include "wordlist.h" #if USE_OPENSSL #include "ssl/ServerBump.h" diff -u -r -N squid-4.0.25/src/format/Format.cc squid-4.1/src/format/Format.cc --- squid-4.0.25/src/format/Format.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/format/Format.cc 2018-07-02 15:26:07.000000000 +1200 @@ -27,7 +27,6 @@ #include "SquidTime.h" #include "Store.h" #include "tools.h" -#include "URL.h" #if USE_OPENSSL #include "ssl/ErrorDetail.h" #include "ssl/ServerBump.h" diff -u -r -N squid-4.0.25/src/FwdState.cc squid-4.1/src/FwdState.cc --- squid-4.0.25/src/FwdState.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/FwdState.cc 2018-07-02 15:26:07.000000000 +1200 @@ -143,7 +143,6 @@ HTTPMSGLOCK(request); serverDestinations.reserve(Config.forward_max_tries); e->lock("FwdState"); - EBIT_SET(e->flags, ENTRY_FWD_HDR_WAIT); flags.connected_okay = false; flags.dont_retry = false; flags.forward_completed = false; @@ -258,7 +257,6 @@ } #endif } else { - EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT); entry->complete(); entry->releaseRequest(); } @@ -528,7 +526,6 @@ debugs(17, 3, HERE << "server FD " << serverConnection()->fd << " not re-forwarding status " << entry->getReply()->sline.status()); else debugs(17, 3, HERE << "server (FD closed) not re-forwarding status " << entry->getReply()->sline.status()); - EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT); entry->complete(); if (!Comm::IsConnOpen(serverConn)) diff -u -r -N squid-4.0.25/src/gopher.cc squid-4.1/src/gopher.cc --- squid-4.0.25/src/gopher.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/gopher.cc 2018-07-02 15:26:07.000000000 +1200 @@ -241,7 +241,6 @@ } assert(entry->isEmpty()); - EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT); HttpReply *reply = new HttpReply; entry->buffer(); diff -u -r -N squid-4.0.25/src/htcp.cc squid-4.1/src/htcp.cc --- squid-4.0.25/src/htcp.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/htcp.cc 2018-07-02 15:26:07.000000000 +1200 @@ -35,7 +35,6 @@ #include "store_key_md5.h" #include "StoreClient.h" #include "tools.h" -#include "URL.h" typedef struct _Countstr Countstr; diff -u -r -N squid-4.0.25/src/http/url_rewriters/LFS/url_lfs_rewrite.8 squid-4.1/src/http/url_rewriters/LFS/url_lfs_rewrite.8 --- squid-4.0.25/src/http/url_rewriters/LFS/url_lfs_rewrite.8 2018-06-12 04:56:20.000000000 +1200 +++ squid-4.1/src/http/url_rewriters/LFS/url_lfs_rewrite.8 2018-07-02 15:39:08.000000000 +1200 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "URL_LFS_REWRITE 8" -.TH URL_LFS_REWRITE 8 "2018-06-11" "perl v5.26.2" "User Contributed Perl Documentation" +.TH URL_LFS_REWRITE 8 "2018-07-02" "perl v5.26.2" "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-4.0.25/src/http.cc squid-4.1/src/http.cc --- squid-4.0.25/src/http.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/http.cc 2018-07-02 15:26:07.000000000 +1200 @@ -56,7 +56,6 @@ #include "Store.h" #include "StrList.h" #include "tools.h" -#include "URL.h" #include "util.h" #if USE_AUTH @@ -928,8 +927,8 @@ // TODO: check whether such responses are shareable. // Do not share for now. entry->makePrivate(false); - if (!fwd->reforwardableStatus(rep->sline.status())) - EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT); + if (fwd->reforwardableStatus(rep->sline.status())) + EBIT_SET(entry->flags, ENTRY_FWD_HDR_WAIT); varyFailure = true; } else { entry->mem_obj->vary_headers = vary; @@ -947,8 +946,8 @@ * If its not a reply that we will re-forward, then * allow the client to get it. */ - if (!fwd->reforwardableStatus(rep->sline.status())) - EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT); + if (fwd->reforwardableStatus(rep->sline.status())) + EBIT_SET(entry->flags, ENTRY_FWD_HDR_WAIT); ReuseDecision decision(entry, statusCode); diff -u -r -N squid-4.0.25/src/HttpRequest.cc squid-4.1/src/HttpRequest.cc --- squid-4.0.25/src/HttpRequest.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/HttpRequest.cc 2018-07-02 15:26:07.000000000 +1200 @@ -30,7 +30,6 @@ #include "sbuf/StringConvert.h" #include "SquidConfig.h" #include "Store.h" -#include "URL.h" #if USE_AUTH #include "auth/UserRequest.h" diff -u -r -N squid-4.0.25/src/HttpRequest.h squid-4.1/src/HttpRequest.h --- squid-4.0.25/src/HttpRequest.h 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/HttpRequest.h 2018-07-02 15:26:07.000000000 +1200 @@ -9,6 +9,7 @@ #ifndef SQUID_HTTPREQUEST_H #define SQUID_HTTPREQUEST_H +#include "anyp/Uri.h" #include "base/CbcPointer.h" #include "dns/forward.h" #include "err_type.h" @@ -18,7 +19,6 @@ #include "MasterXaction.h" #include "Notes.h" #include "RequestFlags.h" -#include "URL.h" #if USE_AUTH #include "auth/UserRequest.h" @@ -100,7 +100,7 @@ public: HttpRequestMethod method; - URL url; ///< the request URI + AnyP::Uri url; ///< the request URI private: #if USE_ADAPTATION diff -u -r -N squid-4.0.25/src/icmp/net_db.cc squid-4.1/src/icmp/net_db.cc --- squid-4.0.25/src/icmp/net_db.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/icmp/net_db.cc 2018-07-02 15:26:07.000000000 +1200 @@ -38,7 +38,6 @@ #include "Store.h" #include "StoreClient.h" #include "tools.h" -#include "URL.h" #include "wordlist.h" #if HAVE_SYS_STAT_H @@ -1095,7 +1094,7 @@ } void -netdbUpdatePeer(const URL &url, CachePeer * e, int irtt, int ihops) +netdbUpdatePeer(const AnyP::Uri &url, CachePeer *e, int irtt, int ihops) { #if USE_ICMP netdbEntry *n; diff -u -r -N squid-4.0.25/src/icmp/net_db.h squid-4.1/src/icmp/net_db.h --- squid-4.0.25/src/icmp/net_db.h 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/icmp/net_db.h 2018-07-02 15:26:07.000000000 +1200 @@ -9,6 +9,7 @@ #ifndef ICMP_NET_DB_H #define ICMP_NET_DB_H +#include "anyp/forward.h" #include "hash.h" #include "ip/forward.h" #include "mem/forward.h" @@ -17,7 +18,6 @@ class HttpRequest; class netdbEntry; class StoreEntry; -class URL; class net_db_name: public hash_link /* must be first */ @@ -73,7 +73,7 @@ void netdbFreeMemory(void); int netdbHostHops(const char *host); int netdbHostRtt(const char *host); -void netdbUpdatePeer(const URL &, CachePeer * e, int rtt, int hops); +void netdbUpdatePeer(const AnyP::Uri &, CachePeer *, int rtt, int hops); void netdbDeleteAddrNetwork(Ip::Address &addr); void netdbBinaryExchange(StoreEntry *); diff -u -r -N squid-4.0.25/src/internal.cc squid-4.1/src/internal.cc --- squid-4.0.25/src/internal.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/internal.cc 2018-07-02 15:26:07.000000000 +1200 @@ -20,7 +20,6 @@ #include "SquidTime.h" #include "Store.h" #include "tools.h" -#include "URL.h" #include "util.h" #include "wordlist.h" @@ -108,7 +107,7 @@ strlen(lc_host) - 1); /* build URI */ - URL tmp(AnyP::PROTO_HTTP); + AnyP::Uri tmp(AnyP::PROTO_HTTP); tmp.host(lc_host); if (port) tmp.port(port); diff -u -r -N squid-4.0.25/src/ipc/Forwarder.cc squid-4.1/src/ipc/Forwarder.cc --- squid-4.0.25/src/ipc/Forwarder.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/ipc/Forwarder.cc 2018-07-02 15:26:07.000000000 +1200 @@ -87,8 +87,10 @@ { debugs(54, 3, HERE); request->requestId = 0; - // Do not clear ENTRY_FWD_HDR_WAIT or do entry->complete() because - // it will trigger our client side processing. Let job cleanup close. + // Do not do entry->complete() because it will trigger our client side + // processing when we no longer own the client-Squid connection. + // Let job cleanup close the client-Squid connection that Coordinator + // now owns. } /// Ipc::Forwarder::requestTimedOut wrapper diff -u -r -N squid-4.0.25/src/log/DB/log_db_daemon.8 squid-4.1/src/log/DB/log_db_daemon.8 --- squid-4.0.25/src/log/DB/log_db_daemon.8 2018-06-12 04:56:21.000000000 +1200 +++ squid-4.1/src/log/DB/log_db_daemon.8 2018-07-02 15:39:08.000000000 +1200 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "LOG_DB_DAEMON 8" -.TH LOG_DB_DAEMON 8 "2018-06-11" "perl v5.26.2" "User Contributed Perl Documentation" +.TH LOG_DB_DAEMON 8 "2018-07-02" "perl v5.26.2" "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-4.0.25/src/main.cc squid-4.1/src/main.cc --- squid-4.0.25/src/main.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/main.cc 2018-07-02 15:26:07.000000000 +1200 @@ -78,7 +78,6 @@ #include "StoreFileSystem.h" #include "tools.h" #include "unlinkd.h" -#include "URL.h" #include "wccp.h" #include "wccp2.h" #include "WinSvc.h" diff -u -r -N squid-4.0.25/src/Makefile.am squid-4.1/src/Makefile.am --- squid-4.0.25/src/Makefile.am 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/Makefile.am 2018-07-02 15:26:07.000000000 +1200 @@ -473,8 +473,6 @@ tunnel.cc \ typedefs.h \ $(UNLINKDSOURCE) \ - url.cc \ - URL.h \ urn.h \ urn.cc \ wccp.h \ @@ -997,7 +995,7 @@ tests/testHttpReply.cc \ tests/testHttpReply.h \ tests/stub_time.cc \ - url.cc \ + tests/stub_libanyp.cc \ wordlist.h \ wordlist.cc nodist_tests_testHttpReply_SOURCES=\ @@ -1120,8 +1118,7 @@ tests/testACLMaxUserIP.cc \ tests/testACLMaxUserIP.h \ tests/stub_time.cc \ - url.cc \ - URL.h \ + tests/stub_libanyp.cc \ MemBuf.cc \ wordlist.h \ wordlist.cc @@ -1373,7 +1370,7 @@ tests/stub_SwapDir.cc \ MemStore.cc \ $(UNLINKDSOURCE) \ - url.cc \ + tests/stub_libanyp.cc \ urn.h \ urn.cc \ wccp2.h \ @@ -1557,7 +1554,7 @@ tests/testStoreSupport.h \ tests/stub_time.cc \ $(UNLINKDSOURCE) \ - url.cc \ + tests/stub_libanyp.cc \ $(WIN32_SOURCE) \ wordlist.h \ wordlist.cc \ @@ -1807,7 +1804,7 @@ tests/stub_tunnel.cc \ MemStore.cc \ $(UNLINKDSOURCE) \ - url.cc \ + tests/stub_libanyp.cc \ urn.h \ urn.cc \ wccp2.h \ @@ -2043,7 +2040,7 @@ tests/stub_tunnel.cc \ MemStore.cc \ $(UNLINKDSOURCE) \ - url.cc \ + tests/stub_libanyp.cc \ urn.h \ urn.cc \ wccp2.h \ @@ -2274,7 +2271,7 @@ tools.cc \ tests/stub_tunnel.cc \ $(UNLINKDSOURCE) \ - url.cc \ + tests/stub_libanyp.cc \ urn.h \ urn.cc \ wccp2.h \ @@ -2379,6 +2376,7 @@ tests/testHttp1Parser.cc \ tests/testHttp1Parser.h \ tests/stub_time.cc \ + tests/stub_libanyp.cc \ wordlist.h \ wordlist.cc nodist_tests_testHttp1Parser_SOURCES = \ @@ -2577,7 +2575,6 @@ tests/stub_tunnel.cc \ tests/stub_SwapDir.cc \ MemStore.cc \ - url.cc \ urn.h \ urn.cc \ wccp2.h \ @@ -2815,7 +2812,7 @@ tests/TestSwapDir.cc \ tests/TestSwapDir.h \ tests/stub_time.cc \ - url.cc \ + tests/stub_libanyp.cc \ wordlist.h \ wordlist.cc @@ -3014,7 +3011,7 @@ HttpHdrCc.cci \ HttpHdrSc.cc \ HttpHdrScTarget.cc \ - url.cc \ + tests/stub_libanyp.cc \ StatCounters.h \ StatCounters.cc \ StatHist.h \ @@ -3214,7 +3211,7 @@ tools.h \ tests/stub_tools.cc \ time.cc \ - url.cc \ + tests/stub_libanyp.cc \ wordlist.h \ wordlist.cc \ $(DELAY_POOL_SOURCE) \ @@ -3441,7 +3438,6 @@ tools.h \ tools.cc \ tests/stub_tunnel.cc \ - url.cc \ urn.h \ urn.cc \ wccp2.h \ diff -u -r -N squid-4.0.25/src/Makefile.in squid-4.1/src/Makefile.in --- squid-4.0.25/src/Makefile.in 2018-06-12 04:47:59.000000000 +1200 +++ squid-4.1/src/Makefile.in 2018-07-02 15:32:02.000000000 +1200 @@ -308,10 +308,10 @@ StoreStats.h StoreSwapLogData.cc StoreSwapLogData.h \ swap_log_op.h Transients.cc Transients.h MemStore.cc \ MemStore.h time.cc TimeOrTag.h tools.h tools.cc tunnel.cc \ - typedefs.h unlinkd.h unlinkd.cc url.cc URL.h urn.h urn.cc \ - wccp.h wccp.cc wccp2.h wccp2.cc whois.h whois.cc wordlist.h \ - wordlist.cc XactionInitiator.h XactionInitiator.cc win32.cc \ - WinSvc.cc LoadableModule.h LoadableModule.cc LoadableModules.h \ + typedefs.h unlinkd.h unlinkd.cc urn.h urn.cc wccp.h wccp.cc \ + wccp2.h wccp2.cc whois.h whois.cc wordlist.h wordlist.cc \ + XactionInitiator.h XactionInitiator.cc win32.cc WinSvc.cc \ + LoadableModule.h LoadableModule.cc LoadableModules.h \ LoadableModules.cc am__objects_1 = AclRegs.$(OBJEXT) AuthReg.$(OBJEXT) am__objects_2 = delay_pools.$(OBJEXT) DelayId.$(OBJEXT) \ @@ -384,7 +384,7 @@ $(am__objects_11) StoreStats.$(OBJEXT) \ StoreSwapLogData.$(OBJEXT) Transients.$(OBJEXT) \ MemStore.$(OBJEXT) time.$(OBJEXT) tools.$(OBJEXT) \ - tunnel.$(OBJEXT) $(am__objects_12) url.$(OBJEXT) urn.$(OBJEXT) \ + tunnel.$(OBJEXT) $(am__objects_12) urn.$(OBJEXT) \ wccp.$(OBJEXT) wccp2.$(OBJEXT) whois.$(OBJEXT) \ wordlist.$(OBJEXT) XactionInitiator.$(OBJEXT) \ $(am__objects_13) $(am__objects_14) $(am__objects_16) @@ -480,7 +480,8 @@ tests/stub_store_swapout.$(OBJEXT) tests/stub_tools.$(OBJEXT) \ tests/stub_cache_manager.$(OBJEXT) tests/stub_UdsOp.$(OBJEXT) \ tests/testACLMaxUserIP.$(OBJEXT) tests/stub_time.$(OBJEXT) \ - url.$(OBJEXT) MemBuf.$(OBJEXT) wordlist.$(OBJEXT) + tests/stub_libanyp.$(OBJEXT) MemBuf.$(OBJEXT) \ + wordlist.$(OBJEXT) am__objects_18 = test_tools.$(OBJEXT) globals.$(OBJEXT) nodist_tests_testACLMaxUserIP_OBJECTS = $(am__objects_18) tests_testACLMaxUserIP_OBJECTS = $(am_tests_testACLMaxUserIP_OBJECTS) \ @@ -569,8 +570,8 @@ StoreIOState.cc tests/stub_StoreMeta.cc StoreMetaUnpacker.cc \ StoreSwapLogData.cc tools.h tools.cc Transients.cc \ tests/stub_tunnel.cc tests/stub_SwapDir.cc MemStore.cc \ - unlinkd.h unlinkd.cc url.cc urn.h urn.cc wccp2.h \ - tests/stub_wccp2.cc whois.h tests/stub_whois.cc \ + unlinkd.h unlinkd.cc tests/stub_libanyp.cc urn.h urn.cc \ + wccp2.h tests/stub_wccp2.cc whois.h tests/stub_whois.cc \ FadingCounter.cc win32.cc wordlist.h wordlist.cc am_tests_testCacheManager_OBJECTS = AccessLogEntry.$(OBJEXT) \ debug.$(OBJEXT) RequestFlags.$(OBJEXT) HttpRequest.$(OBJEXT) \ @@ -626,7 +627,7 @@ StoreSwapLogData.$(OBJEXT) tools.$(OBJEXT) \ Transients.$(OBJEXT) tests/stub_tunnel.$(OBJEXT) \ tests/stub_SwapDir.$(OBJEXT) MemStore.$(OBJEXT) \ - $(am__objects_12) url.$(OBJEXT) urn.$(OBJEXT) \ + $(am__objects_12) tests/stub_libanyp.$(OBJEXT) urn.$(OBJEXT) \ tests/stub_wccp2.$(OBJEXT) tests/stub_whois.$(OBJEXT) \ FadingCounter.$(OBJEXT) $(am__objects_13) wordlist.$(OBJEXT) nodist_tests_testCacheManager_OBJECTS = $(am__objects_17) @@ -733,8 +734,8 @@ tests/stub_store_rebuild.cc tests/stub_UdsOp.cc \ tests/testDiskIO.cc tests/testDiskIO.h \ tests/testStoreSupport.cc tests/testStoreSupport.h \ - tests/stub_time.cc unlinkd.h unlinkd.cc url.cc win32.cc \ - wordlist.h wordlist.cc tools.h tests/stub_tools.cc + tests/stub_time.cc unlinkd.h unlinkd.cc tests/stub_libanyp.cc \ + win32.cc wordlist.h wordlist.cc tools.h tests/stub_tools.cc am_tests_testDiskIO_OBJECTS = AccessLogEntry.$(OBJEXT) \ tests/stub_CacheDigest.$(OBJEXT) cbdata.$(OBJEXT) \ tests/stub_CollapsedForwarding.$(OBJEXT) \ @@ -780,9 +781,9 @@ tests/stub_store_stats.$(OBJEXT) \ tests/stub_store_rebuild.$(OBJEXT) tests/stub_UdsOp.$(OBJEXT) \ tests/testDiskIO.$(OBJEXT) tests/testStoreSupport.$(OBJEXT) \ - tests/stub_time.$(OBJEXT) $(am__objects_12) url.$(OBJEXT) \ - $(am__objects_13) wordlist.$(OBJEXT) \ - tests/stub_tools.$(OBJEXT) + tests/stub_time.$(OBJEXT) $(am__objects_12) \ + tests/stub_libanyp.$(OBJEXT) $(am__objects_13) \ + wordlist.$(OBJEXT) tests/stub_tools.$(OBJEXT) nodist_tests_testDiskIO_OBJECTS = $(am__objects_18) \ SquidMath.$(OBJEXT) swap_log_op.$(OBJEXT) tests_testDiskIO_OBJECTS = $(am_tests_testDiskIO_OBJECTS) \ @@ -873,9 +874,9 @@ tests/stub_libauth.cc tests/stub_libdiskio.cc \ tests/stub_libeui.cc tests/stub_store_stats.cc time.cc tools.h \ tools.cc Transients.cc tests/stub_tunnel.cc MemStore.cc \ - unlinkd.h unlinkd.cc url.cc urn.h urn.cc wccp2.h \ - tests/stub_wccp2.cc whois.h tests/stub_whois.cc win32.cc \ - wordlist.h wordlist.cc + unlinkd.h unlinkd.cc tests/stub_libanyp.cc urn.h urn.cc \ + wccp2.h tests/stub_wccp2.cc whois.h tests/stub_whois.cc \ + win32.cc wordlist.h wordlist.cc am_tests_testEvent_OBJECTS = AccessLogEntry.$(OBJEXT) \ BodyPipe.$(OBJEXT) tests/stub_CacheDigest.$(OBJEXT) \ cache_cf.$(OBJEXT) CachePeer.$(OBJEXT) cache_manager.$(OBJEXT) \ @@ -930,7 +931,7 @@ tests/stub_store_stats.$(OBJEXT) time.$(OBJEXT) \ tools.$(OBJEXT) Transients.$(OBJEXT) \ tests/stub_tunnel.$(OBJEXT) MemStore.$(OBJEXT) \ - $(am__objects_12) url.$(OBJEXT) urn.$(OBJEXT) \ + $(am__objects_12) tests/stub_libanyp.$(OBJEXT) urn.$(OBJEXT) \ tests/stub_wccp2.$(OBJEXT) tests/stub_whois.$(OBJEXT) \ $(am__objects_13) wordlist.$(OBJEXT) nodist_tests_testEvent_OBJECTS = $(am__objects_17) @@ -1012,8 +1013,9 @@ tests/stub_libeui.cc tests/stub_libsecurity.cc \ tests/stub_store_stats.cc time.cc tools.h tools.cc \ Transients.cc tests/stub_tunnel.cc MemStore.cc unlinkd.h \ - unlinkd.cc url.cc urn.h urn.cc wccp2.h tests/stub_wccp2.cc \ - whois.h tests/stub_whois.cc win32.cc wordlist.h wordlist.cc + unlinkd.cc tests/stub_libanyp.cc urn.h urn.cc wccp2.h \ + tests/stub_wccp2.cc whois.h tests/stub_whois.cc win32.cc \ + wordlist.h wordlist.cc am_tests_testEventLoop_OBJECTS = AccessLogEntry.$(OBJEXT) \ BodyPipe.$(OBJEXT) tests/stub_CacheDigest.$(OBJEXT) \ cache_manager.$(OBJEXT) cache_cf.$(OBJEXT) CachePeer.$(OBJEXT) \ @@ -1068,7 +1070,7 @@ tests/stub_store_stats.$(OBJEXT) time.$(OBJEXT) \ tools.$(OBJEXT) Transients.$(OBJEXT) \ tests/stub_tunnel.$(OBJEXT) MemStore.$(OBJEXT) \ - $(am__objects_12) url.$(OBJEXT) urn.$(OBJEXT) \ + $(am__objects_12) tests/stub_libanyp.$(OBJEXT) urn.$(OBJEXT) \ tests/stub_wccp2.$(OBJEXT) tests/stub_whois.$(OBJEXT) \ $(am__objects_13) wordlist.$(OBJEXT) nodist_tests_testEventLoop_OBJECTS = $(am__objects_17) @@ -1106,7 +1108,7 @@ tests/stub_stmem.$(OBJEXT) tests/stub_store.$(OBJEXT) \ tests/stub_store_stats.$(OBJEXT) tests/stub_tools.$(OBJEXT) \ tests/testHttp1Parser.$(OBJEXT) tests/stub_time.$(OBJEXT) \ - wordlist.$(OBJEXT) + tests/stub_libanyp.$(OBJEXT) wordlist.$(OBJEXT) nodist_tests_testHttp1Parser_OBJECTS = $(am__objects_18) tests_testHttp1Parser_OBJECTS = $(am_tests_testHttp1Parser_OBJECTS) \ $(nodist_tests_testHttp1Parser_OBJECTS) @@ -1143,7 +1145,8 @@ tests/stub_StatHist.$(OBJEXT) tests/stub_store.$(OBJEXT) \ tests/stub_store_stats.$(OBJEXT) tests/stub_tools.$(OBJEXT) \ tests/stub_HttpRequest.$(OBJEXT) tests/testHttpReply.$(OBJEXT) \ - tests/stub_time.$(OBJEXT) url.$(OBJEXT) wordlist.$(OBJEXT) + tests/stub_time.$(OBJEXT) tests/stub_libanyp.$(OBJEXT) \ + wordlist.$(OBJEXT) nodist_tests_testHttpReply_OBJECTS = $(am__objects_18) tests_testHttpReply_OBJECTS = $(am_tests_testHttpReply_OBJECTS) \ $(nodist_tests_testHttpReply_OBJECTS) @@ -1216,7 +1219,7 @@ StoreIOState.cc tests/stub_StoreMeta.cc StoreMetaUnpacker.cc \ StoreSwapLogData.cc StrList.h StrList.cc event.cc tools.h \ tools.cc Transients.cc tests/stub_tunnel.cc \ - tests/stub_SwapDir.cc MemStore.cc url.cc urn.h urn.cc wccp2.h \ + tests/stub_SwapDir.cc MemStore.cc urn.h urn.cc wccp2.h \ tests/stub_wccp2.cc whois.h tests/stub_whois.cc \ FadingCounter.cc win32.cc wordlist.h wordlist.cc am_tests_testHttpRequest_OBJECTS = AccessLogEntry.$(OBJEXT) \ @@ -1275,9 +1278,9 @@ StoreSwapLogData.$(OBJEXT) StrList.$(OBJEXT) event.$(OBJEXT) \ tools.$(OBJEXT) Transients.$(OBJEXT) \ tests/stub_tunnel.$(OBJEXT) tests/stub_SwapDir.$(OBJEXT) \ - MemStore.$(OBJEXT) url.$(OBJEXT) urn.$(OBJEXT) \ - tests/stub_wccp2.$(OBJEXT) tests/stub_whois.$(OBJEXT) \ - FadingCounter.$(OBJEXT) $(am__objects_13) wordlist.$(OBJEXT) + MemStore.$(OBJEXT) urn.$(OBJEXT) tests/stub_wccp2.$(OBJEXT) \ + tests/stub_whois.$(OBJEXT) FadingCounter.$(OBJEXT) \ + $(am__objects_13) wordlist.$(OBJEXT) nodist_tests_testHttpRequest_OBJECTS = $(am__objects_17) tests_testHttpRequest_OBJECTS = $(am_tests_testHttpRequest_OBJECTS) \ $(nodist_tests_testHttpRequest_OBJECTS) @@ -1391,14 +1394,14 @@ tests/stub_neighbors.cc tests/stub_Port.cc tests/stub_pconn.cc \ tests/stub_store_client.cc store_rebuild.h \ tests/stub_store_rebuild.cc tests/stub_store_stats.cc tools.h \ - tests/stub_tools.cc time.cc url.cc wordlist.h wordlist.cc \ - CommonPool.h CompositePoolNode.h delay_pools.cc DelayId.cc \ - DelayId.h DelayIdComposite.h DelayBucket.cc DelayBucket.h \ - DelayConfig.cc DelayConfig.h DelayPool.cc DelayPool.h \ - DelayPools.h DelaySpec.cc DelaySpec.h DelayTagged.cc \ - DelayTagged.h DelayUser.cc DelayUser.h DelayVector.cc \ - DelayVector.h NullDelayId.h ClientDelayConfig.cc \ - ClientDelayConfig.h unlinkd.h unlinkd.cc + tests/stub_tools.cc time.cc tests/stub_libanyp.cc wordlist.h \ + wordlist.cc CommonPool.h CompositePoolNode.h delay_pools.cc \ + DelayId.cc DelayId.h DelayIdComposite.h DelayBucket.cc \ + DelayBucket.h DelayConfig.cc DelayConfig.h DelayPool.cc \ + DelayPool.h DelayPools.h DelaySpec.cc DelaySpec.h \ + DelayTagged.cc DelayTagged.h DelayUser.cc DelayUser.h \ + DelayVector.cc DelayVector.h NullDelayId.h \ + ClientDelayConfig.cc ClientDelayConfig.h unlinkd.h unlinkd.cc am_tests_testRock_OBJECTS = AccessLogEntry.$(OBJEXT) cbdata.$(OBJEXT) \ CollapsedForwarding.$(OBJEXT) tests/stub_CacheDigest.$(OBJEXT) \ ConfigOption.$(OBJEXT) ConfigParser.$(OBJEXT) fs_io.$(OBJEXT) \ @@ -1439,7 +1442,7 @@ tests/stub_pconn.$(OBJEXT) tests/stub_store_client.$(OBJEXT) \ tests/stub_store_rebuild.$(OBJEXT) \ tests/stub_store_stats.$(OBJEXT) tests/stub_tools.$(OBJEXT) \ - time.$(OBJEXT) url.$(OBJEXT) wordlist.$(OBJEXT) \ + time.$(OBJEXT) tests/stub_libanyp.$(OBJEXT) wordlist.$(OBJEXT) \ $(am__objects_3) $(am__objects_12) nodist_tests_testRock_OBJECTS = swap_log_op.$(OBJEXT) \ SquidMath.$(OBJEXT) $(am__objects_18) @@ -1547,7 +1550,7 @@ tests/testStoreHashIndex.cc tests/testStoreHashIndex.h \ tests/testStoreSupport.cc tests/testStoreSupport.h \ tests/TestSwapDir.cc tests/TestSwapDir.h tests/stub_time.cc \ - url.cc wordlist.h wordlist.cc + tests/stub_libanyp.cc wordlist.h wordlist.cc am_tests_testStore_OBJECTS = tests/stub_CacheDigest.$(OBJEXT) \ cbdata.$(OBJEXT) tests/stub_CollapsedForwarding.$(OBJEXT) \ ConfigOption.$(OBJEXT) ConfigParser.$(OBJEXT) $(am__objects_3) \ @@ -1593,7 +1596,8 @@ tests/testStoreController.$(OBJEXT) \ tests/testStoreHashIndex.$(OBJEXT) \ tests/testStoreSupport.$(OBJEXT) tests/TestSwapDir.$(OBJEXT) \ - tests/stub_time.$(OBJEXT) url.$(OBJEXT) wordlist.$(OBJEXT) + tests/stub_time.$(OBJEXT) tests/stub_libanyp.$(OBJEXT) \ + wordlist.$(OBJEXT) nodist_tests_testStore_OBJECTS = $(am__objects_18) SquidMath.$(OBJEXT) \ swap_log_op.$(OBJEXT) tests_testStore_OBJECTS = $(am_tests_testStore_OBJECTS) \ @@ -1706,9 +1710,9 @@ tests/stub_store_stats.cc tests/testURL.cc tests/testURL.h \ tests/testUriScheme.cc tests/testUriScheme.h \ tests/stub_time.cc tests/stub_EventLoop.cc tools.h tools.cc \ - tests/stub_tunnel.cc url.cc urn.h urn.cc wccp2.h \ - tests/stub_wccp2.cc whois.h tests/stub_whois.cc \ - FadingCounter.cc win32.cc wordlist.h wordlist.cc + tests/stub_tunnel.cc urn.h urn.cc wccp2.h tests/stub_wccp2.cc \ + whois.h tests/stub_whois.cc FadingCounter.cc win32.cc \ + wordlist.h wordlist.cc am_tests_testURL_OBJECTS = AccessLogEntry.$(OBJEXT) BodyPipe.$(OBJEXT) \ cache_cf.$(OBJEXT) tests/stub_cache_manager.$(OBJEXT) \ tests/stub_CacheDigest.$(OBJEXT) CachePeer.$(OBJEXT) \ @@ -1762,7 +1766,7 @@ tests/stub_store_stats.$(OBJEXT) tests/testURL.$(OBJEXT) \ tests/testUriScheme.$(OBJEXT) tests/stub_time.$(OBJEXT) \ tests/stub_EventLoop.$(OBJEXT) tools.$(OBJEXT) \ - tests/stub_tunnel.$(OBJEXT) url.$(OBJEXT) urn.$(OBJEXT) \ + tests/stub_tunnel.$(OBJEXT) urn.$(OBJEXT) \ tests/stub_wccp2.$(OBJEXT) tests/stub_whois.$(OBJEXT) \ FadingCounter.$(OBJEXT) $(am__objects_13) wordlist.$(OBJEXT) nodist_tests_testURL_OBJECTS = $(am__objects_17) @@ -1829,10 +1833,11 @@ HttpHeaderTools.cc HttpHeader.h HttpHeader.cc ClientInfo.h \ MemBuf.cc HttpHdrContRange.cc HttpHeaderFieldStat.h \ HttpHdrCc.h HttpHdrCc.cc HttpHdrCc.cci HttpHdrSc.cc \ - HttpHdrScTarget.cc url.cc StatCounters.h StatCounters.cc \ - StatHist.h StatHist.cc StrList.h StrList.cc HttpHdrRange.cc \ - ETag.cc tests/stub_errorpage.cc tests/stub_HttpRequest.cc \ - log/access_log.h tests/stub_access_log.cc refresh.h refresh.cc \ + HttpHdrScTarget.cc tests/stub_libanyp.cc StatCounters.h \ + StatCounters.cc StatHist.h StatHist.cc StrList.h StrList.cc \ + HttpHdrRange.cc ETag.cc tests/stub_errorpage.cc \ + tests/stub_HttpRequest.cc log/access_log.h \ + tests/stub_access_log.cc refresh.h refresh.cc \ tests/stub_store_client.cc tools.h tests/stub_tools.cc \ tests/testStoreSupport.cc tests/testStoreSupport.h time.cc \ wordlist.h wordlist.cc @@ -1874,9 +1879,10 @@ HttpHeaderTools.$(OBJEXT) HttpHeader.$(OBJEXT) \ MemBuf.$(OBJEXT) HttpHdrContRange.$(OBJEXT) \ HttpHdrCc.$(OBJEXT) HttpHdrSc.$(OBJEXT) \ - HttpHdrScTarget.$(OBJEXT) url.$(OBJEXT) StatCounters.$(OBJEXT) \ - StatHist.$(OBJEXT) StrList.$(OBJEXT) HttpHdrRange.$(OBJEXT) \ - ETag.$(OBJEXT) tests/stub_errorpage.$(OBJEXT) \ + HttpHdrScTarget.$(OBJEXT) tests/stub_libanyp.$(OBJEXT) \ + StatCounters.$(OBJEXT) StatHist.$(OBJEXT) StrList.$(OBJEXT) \ + HttpHdrRange.$(OBJEXT) ETag.$(OBJEXT) \ + tests/stub_errorpage.$(OBJEXT) \ tests/stub_HttpRequest.$(OBJEXT) \ tests/stub_access_log.$(OBJEXT) refresh.$(OBJEXT) \ tests/stub_store_client.$(OBJEXT) tests/stub_tools.$(OBJEXT) \ @@ -1957,9 +1963,9 @@ tests/stub_libsecurity.cc tests/stub_main_cc.cc \ tests/stub_MemStore.cc tests/stub_store_stats.cc \ tests/stub_EventLoop.cc time.cc tools.h tools.cc \ - tests/stub_tunnel.cc unlinkd.h unlinkd.cc url.cc urn.h urn.cc \ - wccp2.h tests/stub_wccp2.cc whois.h tests/stub_whois.cc \ - win32.cc wordlist.h wordlist.cc + tests/stub_tunnel.cc unlinkd.h unlinkd.cc \ + tests/stub_libanyp.cc urn.h urn.cc wccp2.h tests/stub_wccp2.cc \ + whois.h tests/stub_whois.cc win32.cc wordlist.h wordlist.cc am_tests_test_http_range_OBJECTS = AccessLogEntry.$(OBJEXT) \ BodyPipe.$(OBJEXT) cache_cf.$(OBJEXT) CachePeer.$(OBJEXT) \ cache_manager.$(OBJEXT) tests/stub_CacheDigest.$(OBJEXT) \ @@ -2012,10 +2018,10 @@ tests/stub_libsecurity.$(OBJEXT) tests/stub_main_cc.$(OBJEXT) \ tests/stub_MemStore.$(OBJEXT) tests/stub_store_stats.$(OBJEXT) \ tests/stub_EventLoop.$(OBJEXT) time.$(OBJEXT) tools.$(OBJEXT) \ - tests/stub_tunnel.$(OBJEXT) $(am__objects_12) url.$(OBJEXT) \ - urn.$(OBJEXT) tests/stub_wccp2.$(OBJEXT) \ - tests/stub_whois.$(OBJEXT) $(am__objects_13) \ - wordlist.$(OBJEXT) + tests/stub_tunnel.$(OBJEXT) $(am__objects_12) \ + tests/stub_libanyp.$(OBJEXT) urn.$(OBJEXT) \ + tests/stub_wccp2.$(OBJEXT) tests/stub_whois.$(OBJEXT) \ + $(am__objects_13) wordlist.$(OBJEXT) nodist_tests_test_http_range_OBJECTS = $(am__objects_17) tests_test_http_range_OBJECTS = $(am_tests_test_http_range_OBJECTS) \ $(nodist_tests_test_http_range_OBJECTS) @@ -2906,9 +2912,9 @@ StoreSearch.h StoreStats.cc StoreStats.h StoreSwapLogData.cc \ StoreSwapLogData.h swap_log_op.h Transients.cc Transients.h \ MemStore.cc MemStore.h time.cc TimeOrTag.h tools.h tools.cc \ - tunnel.cc typedefs.h $(UNLINKDSOURCE) url.cc URL.h urn.h \ - urn.cc wccp.h wccp.cc wccp2.h wccp2.cc whois.h whois.cc \ - wordlist.h wordlist.cc XactionInitiator.h XactionInitiator.cc \ + tunnel.cc typedefs.h $(UNLINKDSOURCE) urn.h urn.cc wccp.h \ + wccp.cc wccp2.h wccp2.cc whois.h whois.cc wordlist.h \ + wordlist.cc XactionInitiator.h XactionInitiator.cc \ $(WIN32_SOURCE) $(WINSVC_SOURCE) $(am__append_9) EXTRA_squid_SOURCES = \ $(all_AUTHMODULES) \ @@ -3103,6 +3109,7 @@ tests/stub_ipc.cc \ tests/stub_ipc_Forwarder.cc \ tests/stub_ipc_TypedMsgHdr.cc \ + tests/stub_libanyp.cc \ tests/stub_libauth_acls.cc \ tests/stub_libauth.cc \ tests/stub_libcomm.cc \ @@ -3262,7 +3269,7 @@ tests/testHttpReply.cc \ tests/testHttpReply.h \ tests/stub_time.cc \ - url.cc \ + tests/stub_libanyp.cc \ wordlist.h \ wordlist.cc @@ -3387,8 +3394,7 @@ tests/testACLMaxUserIP.cc \ tests/testACLMaxUserIP.h \ tests/stub_time.cc \ - url.cc \ - URL.h \ + tests/stub_libanyp.cc \ MemBuf.cc \ wordlist.h \ wordlist.cc @@ -3642,7 +3648,7 @@ tests/stub_SwapDir.cc \ MemStore.cc \ $(UNLINKDSOURCE) \ - url.cc \ + tests/stub_libanyp.cc \ urn.h \ urn.cc \ wccp2.h \ @@ -3828,7 +3834,7 @@ tests/testStoreSupport.h \ tests/stub_time.cc \ $(UNLINKDSOURCE) \ - url.cc \ + tests/stub_libanyp.cc \ $(WIN32_SOURCE) \ wordlist.h \ wordlist.cc \ @@ -4083,7 +4089,7 @@ tests/stub_tunnel.cc \ MemStore.cc \ $(UNLINKDSOURCE) \ - url.cc \ + tests/stub_libanyp.cc \ urn.h \ urn.cc \ wccp2.h \ @@ -4320,7 +4326,7 @@ tests/stub_tunnel.cc \ MemStore.cc \ $(UNLINKDSOURCE) \ - url.cc \ + tests/stub_libanyp.cc \ urn.h \ urn.cc \ wccp2.h \ @@ -4553,7 +4559,7 @@ tools.cc \ tests/stub_tunnel.cc \ $(UNLINKDSOURCE) \ - url.cc \ + tests/stub_libanyp.cc \ urn.h \ urn.cc \ wccp2.h \ @@ -4661,6 +4667,7 @@ tests/testHttp1Parser.cc \ tests/testHttp1Parser.h \ tests/stub_time.cc \ + tests/stub_libanyp.cc \ wordlist.h \ wordlist.cc @@ -4860,7 +4867,6 @@ tests/stub_tunnel.cc \ tests/stub_SwapDir.cc \ MemStore.cc \ - url.cc \ urn.h \ urn.cc \ wccp2.h \ @@ -5103,7 +5109,7 @@ tests/TestSwapDir.cc \ tests/TestSwapDir.h \ tests/stub_time.cc \ - url.cc \ + tests/stub_libanyp.cc \ wordlist.h \ wordlist.cc @@ -5301,7 +5307,7 @@ HttpHdrCc.cci \ HttpHdrSc.cc \ HttpHdrScTarget.cc \ - url.cc \ + tests/stub_libanyp.cc \ StatCounters.h \ StatCounters.cc \ StatHist.h \ @@ -5503,7 +5509,7 @@ tools.h \ tests/stub_tools.cc \ time.cc \ - url.cc \ + tests/stub_libanyp.cc \ wordlist.h \ wordlist.cc \ $(DELAY_POOL_SOURCE) \ @@ -5731,7 +5737,6 @@ tools.h \ tools.cc \ tests/stub_tunnel.cc \ - url.cc \ urn.h \ urn.cc \ wccp2.h \ @@ -6275,6 +6280,8 @@ tests/$(DEPDIR)/$(am__dirstamp) tests/stub_time.$(OBJEXT): tests/$(am__dirstamp) \ tests/$(DEPDIR)/$(am__dirstamp) +tests/stub_libanyp.$(OBJEXT): tests/$(am__dirstamp) \ + tests/$(DEPDIR)/$(am__dirstamp) tests/testACLMaxUserIP$(EXEEXT): $(tests_testACLMaxUserIP_OBJECTS) $(tests_testACLMaxUserIP_DEPENDENCIES) $(EXTRA_tests_testACLMaxUserIP_DEPENDENCIES) tests/$(am__dirstamp) @rm -f tests/testACLMaxUserIP$(EXEEXT) @@ -6701,7 +6708,6 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ufsdump.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unlinkd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unlinkd_daemon.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/url.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/urn.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wccp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wccp2.Po@am__quote@ @@ -6753,6 +6759,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/stub_ipc_Forwarder.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/stub_ipc_TypedMsgHdr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/stub_ipcache.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/stub_libanyp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/stub_libauth.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/stub_libauth_acls.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/stub_libcomm.Po@am__quote@ diff -u -r -N squid-4.0.25/src/MemStore.cc squid-4.1/src/MemStore.cc --- squid-4.0.25/src/MemStore.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/MemStore.cc 2018-07-02 15:26:07.000000000 +1200 @@ -556,7 +556,6 @@ const int result = rep->httpMsgParseStep(mb.buf, buf.length, eof); if (result > 0) { assert(rep->pstate == psParsed); - EBIT_CLR(e.flags, ENTRY_FWD_HDR_WAIT); } else if (result < 0) { debugs(20, DBG_IMPORTANT, "Corrupted mem-cached headers: " << e); return false; @@ -657,15 +656,9 @@ void MemStore::copyToShm(StoreEntry &e) { - // prevents remote readers from getting ENTRY_FWD_HDR_WAIT entries and - // not knowing when the wait is over - if (EBIT_TEST(e.flags, ENTRY_FWD_HDR_WAIT)) { - debugs(20, 5, "postponing copying " << e << " for ENTRY_FWD_HDR_WAIT"); - return; - } - assert(map); assert(e.mem_obj); + Must(!EBIT_TEST(e.flags, ENTRY_FWD_HDR_WAIT)); const int64_t eSize = e.mem_obj->endOffset(); if (e.mem_obj->memCache.offset >= eSize) { diff -u -r -N squid-4.0.25/src/mgr/Forwarder.cc squid-4.1/src/mgr/Forwarder.cc --- squid-4.0.25/src/mgr/Forwarder.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/mgr/Forwarder.cc 2018-07-02 15:26:07.000000000 +1200 @@ -37,7 +37,6 @@ HTTPMSGLOCK(httpRequest); entry->lock("Mgr::Forwarder"); - EBIT_SET(entry->flags, ENTRY_FWD_HDR_WAIT); closer = asyncCall(16, 5, "Mgr::Forwarder::noteCommClosed", CommCbMemFunT(this, &Forwarder::noteCommClosed)); @@ -110,7 +109,6 @@ Must(entry != NULL); Must(httpRequest != NULL); - EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT); entry->buffer(); entry->replaceHttpReply(error->BuildHttpReply()); entry->expires = squid_curtime; diff -u -r -N squid-4.0.25/src/neighbors.cc squid-4.1/src/neighbors.cc --- squid-4.0.25/src/neighbors.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/neighbors.cc 2018-07-02 15:26:07.000000000 +1200 @@ -44,7 +44,6 @@ #include "Store.h" #include "store_key_md5.h" #include "tools.h" -#include "URL.h" /* count mcast group peers every 15 minutes */ #define MCAST_COUNT_RATE 900 @@ -111,7 +110,7 @@ } peer_t -neighborType(const CachePeer * p, const URL &url) +neighborType(const CachePeer * p, const AnyP::Uri &url) { const NeighborTypeDomainList *d = NULL; @@ -1374,7 +1373,7 @@ MemObject *mem; icp_common_t *query; int reqnum; - // TODO: use class URL instead of constructing and re-parsing a string + // TODO: use class AnyP::Uri instead of constructing and re-parsing a string LOCAL_ARRAY(char, url, MAX_URL); assert(p->type == PEER_MULTICAST); p->mcast.flags.count_event_pending = false; diff -u -r -N squid-4.0.25/src/neighbors.h squid-4.1/src/neighbors.h --- squid-4.0.25/src/neighbors.h 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/neighbors.h 2018-07-02 15:26:07.000000000 +1200 @@ -11,6 +11,7 @@ #ifndef SQUID_NEIGHBORS_H_ #define SQUID_NEIGHBORS_H_ +#include "anyp/forward.h" #include "enums.h" #include "ICP.h" #include "lookup_t.h" @@ -20,7 +21,6 @@ class HttpRequestMethod; class CachePeer; class StoreEntry; -class URL; CachePeer *getFirstPeer(void); CachePeer *getFirstUpParent(HttpRequest *); @@ -54,7 +54,7 @@ void peerNoteDigestGone(CachePeer * p); int neighborUp(const CachePeer * e); const char *neighborTypeStr(const CachePeer * e); -peer_t neighborType(const CachePeer *, const URL &); +peer_t neighborType(const CachePeer *, const AnyP::Uri &); void peerConnectFailed(CachePeer *); void peerConnectSucceded(CachePeer *); void dump_peer_options(StoreEntry *, CachePeer *); diff -u -r -N squid-4.0.25/src/peer_select.cc squid-4.1/src/peer_select.cc --- squid-4.0.25/src/peer_select.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/peer_select.cc 2018-07-02 15:26:07.000000000 +1200 @@ -33,7 +33,6 @@ #include "SquidConfig.h" #include "SquidTime.h" #include "Store.h" -#include "URL.h" static struct { int timeouts; diff -u -r -N squid-4.0.25/src/refresh.cc squid-4.1/src/refresh.cc --- squid-4.0.25/src/refresh.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/refresh.cc 2018-07-02 15:26:07.000000000 +1200 @@ -22,7 +22,6 @@ #include "SquidConfig.h" #include "SquidTime.h" #include "Store.h" -#include "URL.h" #include "util.h" typedef enum { diff -u -r -N squid-4.0.25/src/security/cert_validators/fake/security_fake_certverify.8 squid-4.1/src/security/cert_validators/fake/security_fake_certverify.8 --- squid-4.0.25/src/security/cert_validators/fake/security_fake_certverify.8 2018-06-12 04:56:21.000000000 +1200 +++ squid-4.1/src/security/cert_validators/fake/security_fake_certverify.8 2018-07-02 15:39:08.000000000 +1200 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SECURITY_FAKE_CERTVERIFY 8" -.TH SECURITY_FAKE_CERTVERIFY 8 "2018-06-11" "perl v5.26.2" "User Contributed Perl Documentation" +.TH SECURITY_FAKE_CERTVERIFY 8 "2018-07-02" "perl v5.26.2" "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-4.0.25/src/servers/FtpServer.cc squid-4.1/src/servers/FtpServer.cc --- squid-4.0.25/src/servers/FtpServer.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/servers/FtpServer.cc 2018-07-02 15:26:07.000000000 +1200 @@ -339,7 +339,7 @@ void Ftp::Server::calcUri(const SBuf *file) { - // TODO: fill a class URL instead of string + // TODO: fill a class AnyP::Uri instead of string uri = "ftp://"; uri.append(host); if (port->ftp_track_dirs && master->workingDir.length()) { @@ -1545,6 +1545,8 @@ ClientHttpRequest *http = pipeline.front()->http; HttpRequest *request = http->request; ACLFilledChecklist bodyContinuationCheck(Config.accessList.forceRequestBodyContinuation, request, NULL); + bodyContinuationCheck.al = http->al; + bodyContinuationCheck.syncAle(request, http->log_uri); if (bodyContinuationCheck.fastCheck().allowed()) { request->forcedBodyContinuation = true; if (checkDataConnPost()) { diff -u -r -N squid-4.0.25/src/servers/Http1Server.cc squid-4.1/src/servers/Http1Server.cc --- squid-4.0.25/src/servers/Http1Server.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/servers/Http1Server.cc 2018-07-02 15:26:07.000000000 +1200 @@ -249,6 +249,8 @@ if (Config.accessList.forceRequestBodyContinuation) { ACLFilledChecklist bodyContinuationCheck(Config.accessList.forceRequestBodyContinuation, request.getRaw(), NULL); + bodyContinuationCheck.al = http->al; + bodyContinuationCheck.syncAle(request.getRaw(), http->log_uri); if (bodyContinuationCheck.fastCheck().allowed()) { debugs(33, 5, "Body Continuation forced"); request->forcedBodyContinuation = true; diff -u -r -N squid-4.0.25/src/ssl/ServerBump.cc squid-4.1/src/ssl/ServerBump.cc --- squid-4.0.25/src/ssl/ServerBump.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/ssl/ServerBump.cc 2018-07-02 15:26:07.000000000 +1200 @@ -9,14 +9,13 @@ /* DEBUG: section 33 Client-side Routines */ #include "squid.h" - +#include "anyp/Uri.h" #include "client_side.h" #include "FwdState.h" #include "http/Stream.h" #include "ssl/ServerBump.h" #include "Store.h" #include "StoreClient.h" -#include "URL.h" CBDATA_NAMESPACED_CLASS_INIT(Ssl, ServerBump); diff -u -r -N squid-4.0.25/src/ssl/support.cc squid-4.1/src/ssl/support.cc --- squid-4.0.25/src/ssl/support.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/ssl/support.cc 2018-07-02 15:26:07.000000000 +1200 @@ -17,6 +17,7 @@ #include "acl/FilledChecklist.h" #include "anyp/PortCfg.h" +#include "anyp/Uri.h" #include "fatal.h" #include "fd.h" #include "fde.h" @@ -31,7 +32,6 @@ #include "ssl/ErrorDetail.h" #include "ssl/gadgets.h" #include "ssl/support.h" -#include "URL.h" #include diff -u -r -N squid-4.0.25/src/store/id_rewriters/file/storeid_file_rewrite.8 squid-4.1/src/store/id_rewriters/file/storeid_file_rewrite.8 --- squid-4.0.25/src/store/id_rewriters/file/storeid_file_rewrite.8 2018-06-12 04:56:19.000000000 +1200 +++ squid-4.1/src/store/id_rewriters/file/storeid_file_rewrite.8 2018-07-02 15:39:07.000000000 +1200 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "STOREID_FILE_REWRITE 8" -.TH STOREID_FILE_REWRITE 8 "2018-06-11" "perl v5.26.2" "User Contributed Perl Documentation" +.TH STOREID_FILE_REWRITE 8 "2018-07-02" "perl v5.26.2" "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-4.0.25/src/store.cc squid-4.1/src/store.cc --- squid-4.0.25/src/store.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/store.cc 2018-07-02 15:26:07.000000000 +1200 @@ -828,8 +828,12 @@ storeGetMemSpace(writeBuffer.length); mem_obj->write(writeBuffer); - if (!EBIT_TEST(flags, DELAY_SENDING)) - invokeHandlers(); + if (EBIT_TEST(flags, ENTRY_FWD_HDR_WAIT) && !mem_obj->readAheadPolicyCanRead()) { + debugs(20, 3, "allow Store clients to get entry content after buffering too much for " << *this); + EBIT_CLR(flags, ENTRY_FWD_HDR_WAIT); + } + + invokeHandlers(); } /* Append incoming data from a primary server to an entry. */ @@ -1073,6 +1077,9 @@ { debugs(20, 3, "storeComplete: '" << getMD5Text() << "'"); + // To preserve forwarding retries, call FwdState::complete() instead. + EBIT_CLR(flags, ENTRY_FWD_HDR_WAIT); + if (store_status != STORE_PENDING) { /* * if we're not STORE_PENDING, then probably we got aborted @@ -1129,6 +1136,9 @@ EBIT_SET(flags, ENTRY_ABORTED); + // allow the Store clients to be told about the problem + EBIT_CLR(flags, ENTRY_FWD_HDR_WAIT); + setMemStatus(NOT_IN_MEMORY); store_status = STORE_OK; @@ -1823,7 +1833,6 @@ buffer(); rep->packHeadersInto(this); mem_obj->markEndOfReplyHeaders(); - EBIT_CLR(flags, ENTRY_FWD_HDR_WAIT); rep->body.packInto(this); flush(); diff -u -r -N squid-4.0.25/src/store_client.cc squid-4.1/src/store_client.cc --- squid-4.0.25/src/store_client.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/store_client.cc 2018-07-02 15:26:07.000000000 +1200 @@ -279,11 +279,6 @@ return; } - if (EBIT_TEST(e->flags, ENTRY_FWD_HDR_WAIT)) { - debugs(90, 5, "storeClientCopy2: returning because ENTRY_FWD_HDR_WAIT set"); - return; - } - if (sc->flags.store_copying) { sc->flags.copy_event_pending = true; debugs(90, 3, "storeClientCopy2: Queueing storeClientCopyEvent()"); @@ -711,6 +706,15 @@ void StoreEntry::invokeHandlers() { + if (EBIT_TEST(flags, DELAY_SENDING)) { + debugs(90, 3, "DELAY_SENDING is on, exiting " << *this); + return; + } + if (EBIT_TEST(flags, ENTRY_FWD_HDR_WAIT)) { + debugs(90, 3, "ENTRY_FWD_HDR_WAIT is on, exiting " << *this); + return; + } + /* Commit what we can to disk, if appropriate */ swapOut(); int i = 0; diff -u -r -N squid-4.0.25/src/store_key_md5.cc squid-4.1/src/store_key_md5.cc --- squid-4.0.25/src/store_key_md5.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/store_key_md5.cc 2018-07-02 15:26:07.000000000 +1200 @@ -12,7 +12,6 @@ #include "HttpRequest.h" #include "md5.h" #include "store_key_md5.h" -#include "URL.h" static cache_key null_key[SQUID_MD5_DIGEST_LENGTH]; diff -u -r -N squid-4.0.25/src/tests/stub_libanyp.cc squid-4.1/src/tests/stub_libanyp.cc --- squid-4.0.25/src/tests/stub_libanyp.cc 1970-01-01 12:00:00.000000000 +1200 +++ squid-4.1/src/tests/stub_libanyp.cc 2018-07-02 15:26:07.000000000 +1200 @@ -0,0 +1,44 @@ +/* + * Copyright (C) 1996-2018 The Squid Software Foundation and contributors + * + * Squid software is distributed under GPLv2+ license and includes + * contributions from numerous individuals and organizations. + * Please see the COPYING and CONTRIBUTORS files for details. + */ + +#include "squid.h" + +#define STUB_API "anyp/libanyp.la" +#include "tests/STUB.h" + +#include "anyp/Uri.h" +AnyP::Uri::Uri(AnyP::UriScheme const &) {STUB} +void AnyP::Uri::touch() STUB +bool AnyP::Uri::parse(const HttpRequestMethod&, const char *) STUB_RETVAL(true) +void AnyP::Uri::host(const char *) STUB +static SBuf nil; +const SBuf &AnyP::Uri::path() const STUB_RETVAL(nil) +const SBuf &AnyP::Uri::SlashPath() +{ + static SBuf slash("/"); + return slash; +} +const SBuf &AnyP::Uri::Asterisk() +{ + static SBuf asterisk("*"); + return asterisk; +} +SBuf &AnyP::Uri::authority(bool) const STUB_RETVAL(nil) +SBuf &AnyP::Uri::absolute() const STUB_RETVAL(nil) +void urlInitialize() STUB +char *urlCanonicalClean(const HttpRequest *) STUB_RETVAL(nullptr) +const char *urlCanonicalFakeHttps(const HttpRequest *) STUB_RETVAL(nullptr) +bool urlIsRelative(const char *) STUB_RETVAL(false) +char *urlMakeAbsolute(const HttpRequest *, const char *)STUB_RETVAL(nullptr) +char *urlRInternal(const char *, unsigned short, const char *, const char *) STUB_RETVAL(nullptr) +char *urlInternal(const char *, const char *) STUB_RETVAL(nullptr) +int matchDomainName(const char *, const char *, uint) STUB_RETVAL(0) +int urlCheckRequest(const HttpRequest *) STUB_RETVAL(0) +char *urlHostname(const char *) STUB_RETVAL(nullptr) +void urlExtMethodConfigure() STUB + diff -u -r -N squid-4.0.25/src/tests/stub_libicmp.cc squid-4.1/src/tests/stub_libicmp.cc --- squid-4.0.25/src/tests/stub_libicmp.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/tests/stub_libicmp.cc 2018-07-02 15:26:07.000000000 +1200 @@ -30,7 +30,7 @@ void netdbFreeMemory(void) STUB int netdbHostHops(const char *host) STUB_RETVAL(-1) int netdbHostRtt(const char *host) STUB_RETVAL(-1) -void netdbUpdatePeer(const URL &, CachePeer * e, int rtt, int hops) STUB +void netdbUpdatePeer(const AnyP::Uri &, CachePeer *, int, int) STUB void netdbDeleteAddrNetwork(Ip::Address &addr) STUB void netdbBinaryExchange(StoreEntry *) STUB void netdbExchangeStart(void *) STUB diff -u -r -N squid-4.0.25/src/tests/Stub.list squid-4.1/src/tests/Stub.list --- squid-4.0.25/src/tests/Stub.list 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/tests/Stub.list 2018-07-02 15:26:07.000000000 +1200 @@ -41,6 +41,7 @@ tests/stub_ipc.cc \ tests/stub_ipc_Forwarder.cc \ tests/stub_ipc_TypedMsgHdr.cc \ + tests/stub_libanyp.cc \ tests/stub_libauth_acls.cc \ tests/stub_libauth.cc \ tests/stub_libcomm.cc \ diff -u -r -N squid-4.0.25/src/tests/testURL.cc squid-4.1/src/tests/testURL.cc --- squid-4.0.25/src/tests/testURL.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/tests/testURL.cc 2018-07-02 15:26:07.000000000 +1200 @@ -10,10 +10,10 @@ #include +#include "anyp/Uri.h" #include "Debug.h" -#include "testURL.h" +#include "tests/testURL.h" #include "unitTestMain.h" -#include "URL.h" #include @@ -36,11 +36,11 @@ testURL::testConstructScheme() { AnyP::UriScheme empty_scheme; - URL protoless_url(AnyP::PROTO_NONE); + AnyP::Uri protoless_url(AnyP::PROTO_NONE); CPPUNIT_ASSERT_EQUAL(empty_scheme, protoless_url.getScheme()); AnyP::UriScheme ftp_scheme(AnyP::PROTO_FTP); - URL ftp_url(AnyP::PROTO_FTP); + AnyP::Uri ftp_url(AnyP::PROTO_FTP); CPPUNIT_ASSERT_EQUAL(ftp_scheme, ftp_url.getScheme()); } @@ -53,10 +53,10 @@ testURL::testDefaultConstructor() { AnyP::UriScheme aScheme; - URL aUrl; + AnyP::Uri aUrl; CPPUNIT_ASSERT_EQUAL(aScheme, aUrl.getScheme()); - URL *urlPointer = new URL; + auto *urlPointer = new AnyP::Uri; CPPUNIT_ASSERT(urlPointer != NULL); delete urlPointer; } diff -u -r -N squid-4.0.25/src/url.cc squid-4.1/src/url.cc --- squid-4.0.25/src/url.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/url.cc 1970-01-01 12:00:00.000000000 +1200 @@ -1,938 +0,0 @@ -/* - * Copyright (C) 1996-2018 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -/* DEBUG: section 23 URL Parsing */ - -#include "squid.h" -#include "globals.h" -#include "HttpRequest.h" -#include "rfc1738.h" -#include "SquidConfig.h" -#include "SquidString.h" -#include "URL.h" - -static const char valid_hostname_chars_u[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789-._" - "[:]" - ; -static const char valid_hostname_chars[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789-." - "[:]" - ; - -const SBuf & -URL::Asterisk() -{ - static SBuf star("*"); - return star; -} - -const SBuf & -URL::SlashPath() -{ - static SBuf slash("/"); - return slash; -} - -void -URL::host(const char *src) -{ - hostAddr_.setEmpty(); - hostAddr_ = src; - if (hostAddr_.isAnyAddr()) { - xstrncpy(host_, src, sizeof(host_)); - hostIsNumeric_ = false; - } else { - hostAddr_.toHostStr(host_, sizeof(host_)); - debugs(23, 3, "given IP: " << hostAddr_); - hostIsNumeric_ = 1; - } - touch(); -} - -const SBuf & -URL::path() const -{ - // RFC 3986 section 3.3 says path can be empty (path-abempty). - // RFC 7230 sections 2.7.3, 5.3.1, 5.7.2 - says path cannot be empty, default to "/" - // at least when sending and using. We must still accept path-abempty as input. - if (path_.isEmpty() && (scheme_ == AnyP::PROTO_HTTP || scheme_ == AnyP::PROTO_HTTPS)) - return SlashPath(); - - return path_; -} - -void -urlInitialize(void) -{ - debugs(23, 5, "urlInitialize: Initializing..."); - /* this ensures that the number of protocol strings is the same as - * the enum slots allocated because the last enum is always 'MAX'. - */ - assert(strcmp(AnyP::ProtocolType_str[AnyP::PROTO_MAX], "MAX") == 0); - /* - * These test that our matchDomainName() function works the - * way we expect it to. - */ - assert(0 == matchDomainName("foo.com", "foo.com")); - assert(0 == matchDomainName(".foo.com", "foo.com")); - assert(0 == matchDomainName("foo.com", ".foo.com")); - assert(0 == matchDomainName(".foo.com", ".foo.com")); - assert(0 == matchDomainName("x.foo.com", ".foo.com")); - assert(0 == matchDomainName("y.x.foo.com", ".foo.com")); - assert(0 != matchDomainName("x.foo.com", "foo.com")); - assert(0 != matchDomainName("foo.com", "x.foo.com")); - assert(0 != matchDomainName("bar.com", "foo.com")); - assert(0 != matchDomainName(".bar.com", "foo.com")); - assert(0 != matchDomainName(".bar.com", ".foo.com")); - assert(0 != matchDomainName("bar.com", ".foo.com")); - assert(0 < matchDomainName("zzz.com", "foo.com")); - assert(0 > matchDomainName("aaa.com", "foo.com")); - assert(0 == matchDomainName("FOO.com", "foo.COM")); - assert(0 < matchDomainName("bfoo.com", "afoo.com")); - assert(0 > matchDomainName("afoo.com", "bfoo.com")); - assert(0 < matchDomainName("x-foo.com", ".foo.com")); - - assert(0 == matchDomainName(".foo.com", ".foo.com", mdnRejectSubsubDomains)); - assert(0 == matchDomainName("x.foo.com", ".foo.com", mdnRejectSubsubDomains)); - assert(0 != matchDomainName("y.x.foo.com", ".foo.com", mdnRejectSubsubDomains)); - assert(0 != matchDomainName(".x.foo.com", ".foo.com", mdnRejectSubsubDomains)); - - assert(0 == matchDomainName("*.foo.com", "x.foo.com", mdnHonorWildcards)); - assert(0 == matchDomainName("*.foo.com", ".x.foo.com", mdnHonorWildcards)); - assert(0 == matchDomainName("*.foo.com", ".foo.com", mdnHonorWildcards)); - assert(0 != matchDomainName("*.foo.com", "foo.com", mdnHonorWildcards)); - - /* more cases? */ -} - -/** - * Parse the scheme name from string b, into protocol type. - * The string must be 0-terminated. - */ -AnyP::ProtocolType -urlParseProtocol(const char *b) -{ - // make e point to the ':' character - const char *e = b + strcspn(b, ":"); - int len = e - b; - - /* test common stuff first */ - - if (strncasecmp(b, "http", len) == 0) - return AnyP::PROTO_HTTP; - - if (strncasecmp(b, "ftp", len) == 0) - return AnyP::PROTO_FTP; - - if (strncasecmp(b, "https", len) == 0) - return AnyP::PROTO_HTTPS; - - if (strncasecmp(b, "file", len) == 0) - return AnyP::PROTO_FTP; - - if (strncasecmp(b, "coap", len) == 0) - return AnyP::PROTO_COAP; - - if (strncasecmp(b, "coaps", len) == 0) - return AnyP::PROTO_COAPS; - - if (strncasecmp(b, "gopher", len) == 0) - return AnyP::PROTO_GOPHER; - - if (strncasecmp(b, "wais", len) == 0) - return AnyP::PROTO_WAIS; - - if (strncasecmp(b, "cache_object", len) == 0) - return AnyP::PROTO_CACHE_OBJECT; - - if (strncasecmp(b, "urn", len) == 0) - return AnyP::PROTO_URN; - - if (strncasecmp(b, "whois", len) == 0) - return AnyP::PROTO_WHOIS; - - if (len > 0) - return AnyP::PROTO_UNKNOWN; - - return AnyP::PROTO_NONE; -} - -/* - * Parse a URI/URL. - * - * Stores parsed values in the `request` argument. - * - * This abuses HttpRequest as a way of representing the parsed url - * and its components. - * method is used to switch parsers and to init the HttpRequest. - * If method is Http::METHOD_CONNECT, then rather than a URL a hostname:port is - * looked for. - * The url is non const so that if its too long we can NULL-terminate it in place. - */ - -/* - * This routine parses a URL. Its assumed that the URL is complete - - * ie, the end of the string is the end of the URL. Don't pass a partial - * URL here as this routine doesn't have any way of knowing whether - * its partial or not (ie, it handles the case of no trailing slash as - * being "end of host with implied path of /". - */ -bool -URL::parse(const HttpRequestMethod& method, const char *url) -{ - LOCAL_ARRAY(char, proto, MAX_URL); - LOCAL_ARRAY(char, login, MAX_URL); - LOCAL_ARRAY(char, foundHost, MAX_URL); - LOCAL_ARRAY(char, urlpath, MAX_URL); - char *t = NULL; - char *q = NULL; - int foundPort; - AnyP::ProtocolType protocol = AnyP::PROTO_NONE; - int l; - int i; - const char *src; - char *dst; - proto[0] = foundHost[0] = urlpath[0] = login[0] = '\0'; - - if ((l = strlen(url)) + Config.appendDomainLen > (MAX_URL - 1)) { - debugs(23, DBG_IMPORTANT, MYNAME << "URL too large (" << l << " bytes)"); - return false; - } - if (method == Http::METHOD_CONNECT) { - /* - * RFC 7230 section 5.3.3: authority-form = authority - * "excluding any userinfo and its "@" delimiter" - * - * RFC 3986 section 3.2: authority = [ userinfo "@" ] host [ ":" port ] - * - * As an HTTP(S) proxy we assume HTTPS (443) if no port provided. - */ - foundPort = 443; - - if (sscanf(url, "[%[^]]]:%d", foundHost, &foundPort) < 1) - if (sscanf(url, "%[^:]:%d", foundHost, &foundPort) < 1) - return false; - - } else if ((method == Http::METHOD_OPTIONS || method == Http::METHOD_TRACE) && - URL::Asterisk().cmp(url) == 0) { - parseFinish(AnyP::PROTO_HTTP, nullptr, url, foundHost, SBuf(), 80 /* HTTP default port */); - return true; - } else if (strncmp(url, "urn:", 4) == 0) { - debugs(23, 3, "Split URI '" << url << "' into proto='urn', path='" << (url+4) << "'"); - debugs(50, 5, "urn=" << (url+4)); - setScheme(AnyP::PROTO_URN, nullptr); - path(url + 4); - return true; - } else { - /* Parse the URL: */ - src = url; - i = 0; - /* Find first : - everything before is protocol */ - for (i = 0, dst = proto; i < l && *src != ':'; ++i, ++src, ++dst) { - *dst = *src; - } - if (i >= l) - return false; - *dst = '\0'; - - /* Then its :// */ - if ((i+3) > l || *src != ':' || *(src + 1) != '/' || *(src + 2) != '/') - return false; - i += 3; - src += 3; - - /* Then everything until first /; thats host (and port; which we'll look for here later) */ - // bug 1881: If we don't get a "/" then we imply it was there - // bug 3074: We could just be given a "?" or "#". These also imply "/" - // bug 3233: whitespace is also a hostname delimiter. - for (dst = foundHost; i < l && *src != '/' && *src != '?' && *src != '#' && *src != '\0' && !xisspace(*src); ++i, ++src, ++dst) { - *dst = *src; - } - - /* - * We can't check for "i >= l" here because we could be at the end of the line - * and have a perfectly valid URL w/ no trailing '/'. In this case we assume we've - * been -given- a valid URL and the path is just '/'. - */ - if (i > l) - return false; - *dst = '\0'; - - // bug 3074: received 'path' starting with '?', '#', or '\0' implies '/' - if (*src == '?' || *src == '#' || *src == '\0') { - urlpath[0] = '/'; - dst = &urlpath[1]; - } else { - dst = urlpath; - } - /* Then everything from / (inclusive) until \r\n or \0 - thats urlpath */ - for (; i < l && *src != '\r' && *src != '\n' && *src != '\0'; ++i, ++src, ++dst) { - *dst = *src; - } - - /* We -could- be at the end of the buffer here */ - if (i > l) - return false; - /* If the URL path is empty we set it to be "/" */ - if (dst == urlpath) { - *dst = '/'; - ++dst; - } - *dst = '\0'; - - protocol = urlParseProtocol(proto); - foundPort = AnyP::UriScheme(protocol).defaultPort(); - - /* Is there any login information? (we should eventually parse it above) */ - t = strrchr(foundHost, '@'); - if (t != NULL) { - strncpy((char *) login, (char *) foundHost, sizeof(login)-1); - login[sizeof(login)-1] = '\0'; - t = strrchr(login, '@'); - *t = 0; - strncpy((char *) foundHost, t + 1, sizeof(foundHost)-1); - foundHost[sizeof(foundHost)-1] = '\0'; - // Bug 4498: URL-unescape the login info after extraction - rfc1738_unescape(login); - } - - /* Is there any host information? (we should eventually parse it above) */ - if (*foundHost == '[') { - /* strip any IPA brackets. valid under IPv6. */ - dst = foundHost; - /* only for IPv6 sadly, pre-IPv6/URL code can't handle the clean result properly anyway. */ - src = foundHost; - ++src; - l = strlen(foundHost); - i = 1; - for (; i < l && *src != ']' && *src != '\0'; ++i, ++src, ++dst) { - *dst = *src; - } - - /* we moved in-place, so truncate the actual hostname found */ - *dst = '\0'; - ++dst; - - /* skip ahead to either start of port, or original EOS */ - while (*dst != '\0' && *dst != ':') - ++dst; - t = dst; - } else { - t = strrchr(foundHost, ':'); - - if (t != strchr(foundHost,':') ) { - /* RFC 2732 states IPv6 "SHOULD" be bracketed. allowing for times when its not. */ - /* RFC 3986 'update' simply modifies this to an "is" with no emphasis at all! */ - /* therefore we MUST accept the case where they are not bracketed at all. */ - t = NULL; - } - } - - // Bug 3183 sanity check: If scheme is present, host must be too. - if (protocol != AnyP::PROTO_NONE && foundHost[0] == '\0') { - debugs(23, DBG_IMPORTANT, "SECURITY ALERT: Missing hostname in URL '" << url << "'. see access.log for details."); - return false; - } - - if (t && *t == ':') { - *t = '\0'; - ++t; - foundPort = atoi(t); - } - } - - for (t = foundHost; *t; ++t) - *t = xtolower(*t); - - if (stringHasWhitespace(foundHost)) { - if (URI_WHITESPACE_STRIP == Config.uri_whitespace) { - t = q = foundHost; - while (*t) { - if (!xisspace(*t)) { - *q = *t; - ++q; - } - ++t; - } - *q = '\0'; - } - } - - debugs(23, 3, "Split URL '" << url << "' into proto='" << proto << "', host='" << foundHost << "', port='" << foundPort << "', path='" << urlpath << "'"); - - if (Config.onoff.check_hostnames && - strspn(foundHost, Config.onoff.allow_underscore ? valid_hostname_chars_u : valid_hostname_chars) != strlen(foundHost)) { - debugs(23, DBG_IMPORTANT, MYNAME << "Illegal character in hostname '" << foundHost << "'"); - return false; - } - - /* For IPV6 addresses also check for a colon */ - if (Config.appendDomain && !strchr(foundHost, '.') && !strchr(foundHost, ':')) - strncat(foundHost, Config.appendDomain, SQUIDHOSTNAMELEN - strlen(foundHost) - 1); - - /* remove trailing dots from hostnames */ - while ((l = strlen(foundHost)) > 0 && foundHost[--l] == '.') - foundHost[l] = '\0'; - - /* reject duplicate or leading dots */ - if (strstr(foundHost, "..") || *foundHost == '.') { - debugs(23, DBG_IMPORTANT, MYNAME << "Illegal hostname '" << foundHost << "'"); - return false; - } - - if (foundPort < 1 || foundPort > 65535) { - debugs(23, 3, "Invalid port '" << foundPort << "'"); - return false; - } - -#if HARDCODE_DENY_PORTS - /* These ports are filtered in the default squid.conf, but - * maybe someone wants them hardcoded... */ - if (foundPort == 7 || foundPort == 9 || foundPort == 19) { - debugs(23, DBG_CRITICAL, MYNAME << "Deny access to port " << foundPort); - return false; - } -#endif - - if (stringHasWhitespace(urlpath)) { - debugs(23, 2, "URI has whitespace: {" << url << "}"); - - switch (Config.uri_whitespace) { - - case URI_WHITESPACE_DENY: - return false; - - case URI_WHITESPACE_ALLOW: - break; - - case URI_WHITESPACE_ENCODE: - t = rfc1738_escape_unescaped(urlpath); - xstrncpy(urlpath, t, MAX_URL); - break; - - case URI_WHITESPACE_CHOP: - *(urlpath + strcspn(urlpath, w_space)) = '\0'; - break; - - case URI_WHITESPACE_STRIP: - default: - t = q = urlpath; - while (*t) { - if (!xisspace(*t)) { - *q = *t; - ++q; - } - ++t; - } - *q = '\0'; - } - } - - parseFinish(protocol, proto, urlpath, foundHost, SBuf(login), foundPort); - return true; -} - -/// Update the URL object with parsed URI data. -void -URL::parseFinish(const AnyP::ProtocolType protocol, - const char *const protoStr, // for unknown protocols - const char *const aUrlPath, - const char *const aHost, - const SBuf &aLogin, - const int aPort) -{ - setScheme(protocol, protoStr); - path(aUrlPath); - host(aHost); - userInfo(aLogin); - port(aPort); -} - -void -URL::touch() -{ - absolute_.clear(); - authorityHttp_.clear(); - authorityWithPort_.clear(); -} - -SBuf & -URL::authority(bool requirePort) const -{ - if (authorityHttp_.isEmpty()) { - - // both formats contain Host/IP - authorityWithPort_.append(host()); - authorityHttp_ = authorityWithPort_; - - // authorityForm_ only has :port if it is non-default - authorityWithPort_.appendf(":%u",port()); - if (port() != getScheme().defaultPort()) - authorityHttp_ = authorityWithPort_; - } - - return requirePort ? authorityWithPort_ : authorityHttp_; -} - -SBuf & -URL::absolute() const -{ - if (absolute_.isEmpty()) { - // TODO: most URL will be much shorter, avoid allocating this much - absolute_.reserveCapacity(MAX_URL); - - absolute_.append(getScheme().image()); - absolute_.append(":",1); - if (getScheme() != AnyP::PROTO_URN) { - absolute_.append("//", 2); - const bool omitUserInfo = getScheme() == AnyP::PROTO_HTTP || - getScheme() != AnyP::PROTO_HTTPS || - userInfo().isEmpty(); - if (!omitUserInfo) { - absolute_.append(userInfo()); - absolute_.append("@", 1); - } - absolute_.append(authority()); - } - absolute_.append(path()); - } - - return absolute_; -} - -/** \todo AYJ: Performance: This is an *almost* duplicate of HttpRequest::effectiveRequestUri(). But elides the query-string. - * After copying it on in the first place! Would be less code to merge the two with a flag parameter. - * and never copy the query-string part in the first place - */ -char * -urlCanonicalClean(const HttpRequest * request) -{ - LOCAL_ARRAY(char, buf, MAX_URL); - - snprintf(buf, sizeof(buf), SQUIDSBUFPH, SQUIDSBUFPRINT(request->effectiveRequestUri())); - buf[sizeof(buf)-1] = '\0'; - - // URN, CONNECT method, and non-stripped URIs can go straight out - if (Config.onoff.strip_query_terms && !(request->method == Http::METHOD_CONNECT || request->url.getScheme() == AnyP::PROTO_URN)) { - // strip anything AFTER a question-mark - // leaving the '?' in place - if (auto t = strchr(buf, '?')) { - *(++t) = '\0'; - } - } - - if (stringHasCntl(buf)) - xstrncpy(buf, rfc1738_escape_unescaped(buf), MAX_URL); - - return buf; -} - -/** - * Yet another alternative to urlCanonical. - * This one adds the https:// parts to Http::METHOD_CONNECT URL - * for use in error page outputs. - * Luckily we can leverage the others instead of duplicating. - */ -const char * -urlCanonicalFakeHttps(const HttpRequest * request) -{ - LOCAL_ARRAY(char, buf, MAX_URL); - - // method CONNECT and port HTTPS - if (request->method == Http::METHOD_CONNECT && request->url.port() == 443) { - snprintf(buf, MAX_URL, "https://%s/*", request->url.host()); - return buf; - } - - // else do the normal complete canonical thing. - return urlCanonicalClean(request); -} - -/* - * Test if a URL is relative. - * - * RFC 2396, Section 5 (Page 17) implies that in a relative URL, a '/' will - * appear before a ':'. - */ -bool -urlIsRelative(const char *url) -{ - const char *p; - - if (url == NULL) { - return (false); - } - if (*url == '\0') { - return (false); - } - - for (p = url; *p != '\0' && *p != ':' && *p != '/'; ++p); - - if (*p == ':') { - return (false); - } - return (true); -} - -/* - * Convert a relative URL to an absolute URL using the context of a given - * request. - * - * It is assumed that you have already ensured that the URL is relative. - * - * If NULL is returned it is an indication that the method in use in the - * request does not distinguish between relative and absolute and you should - * use the url unchanged. - * - * If non-NULL is returned, it is up to the caller to free the resulting - * memory using safe_free(). - */ -char * -urlMakeAbsolute(const HttpRequest * req, const char *relUrl) -{ - - if (req->method.id() == Http::METHOD_CONNECT) { - return (NULL); - } - - char *urlbuf = (char *)xmalloc(MAX_URL * sizeof(char)); - - if (req->url.getScheme() == AnyP::PROTO_URN) { - // XXX: this is what the original code did, but it seems to break the - // intended behaviour of this function. It returns the stored URN path, - // not converting the given one into a URN... - snprintf(urlbuf, MAX_URL, SQUIDSBUFPH, SQUIDSBUFPRINT(req->url.absolute())); - return (urlbuf); - } - - SBuf authorityForm = req->url.authority(); // host[:port] - const SBuf &scheme = req->url.getScheme().image(); - size_t urllen = snprintf(urlbuf, MAX_URL, SQUIDSBUFPH "://" SQUIDSBUFPH "%s" SQUIDSBUFPH, - SQUIDSBUFPRINT(scheme), - SQUIDSBUFPRINT(req->url.userInfo()), - !req->url.userInfo().isEmpty() ? "@" : "", - SQUIDSBUFPRINT(authorityForm)); - - // if the first char is '/' assume its a relative path - // XXX: this breaks on scheme-relative URLs, - // but we should not see those outside ESI, and rarely there. - // XXX: also breaks on any URL containing a '/' in the query-string portion - if (relUrl[0] == '/') { - xstrncpy(&urlbuf[urllen], relUrl, MAX_URL - urllen - 1); - } else { - SBuf path = req->url.path(); - SBuf::size_type lastSlashPos = path.rfind('/'); - - if (lastSlashPos == SBuf::npos) { - // replace the whole path with the given bit(s) - urlbuf[urllen] = '/'; - ++urllen; - xstrncpy(&urlbuf[urllen], relUrl, MAX_URL - urllen - 1); - } else { - // replace only the last (file?) segment with the given bit(s) - ++lastSlashPos; - if (lastSlashPos > MAX_URL - urllen - 1) { - // XXX: crops bits in the middle of the combined URL. - lastSlashPos = MAX_URL - urllen - 1; - } - SBufToCstring(&urlbuf[urllen], path.substr(0,lastSlashPos)); - urllen += lastSlashPos; - if (urllen + 1 < MAX_URL) { - xstrncpy(&urlbuf[urllen], relUrl, MAX_URL - urllen - 1); - } - } - } - - return (urlbuf); -} - -int -matchDomainName(const char *h, const char *d, uint flags) -{ - int dl; - int hl; - - const bool hostIncludesSubdomains = (*h == '.'); - while ('.' == *h) - ++h; - - hl = strlen(h); - - if (hl == 0) - return -1; - - dl = strlen(d); - - /* - * Start at the ends of the two strings and work towards the - * beginning. - */ - while (xtolower(h[--hl]) == xtolower(d[--dl])) { - if (hl == 0 && dl == 0) { - /* - * We made it all the way to the beginning of both - * strings without finding any difference. - */ - return 0; - } - - if (0 == hl) { - /* - * The host string is shorter than the domain string. - * There is only one case when this can be a match. - * If the domain is just one character longer, and if - * that character is a leading '.' then we call it a - * match. - */ - - if (1 == dl && '.' == d[0]) - return 0; - else - return -1; - } - - if (0 == dl) { - /* - * The domain string is shorter than the host string. - * This is a match only if the first domain character - * is a leading '.'. - */ - - if ('.' == d[0]) { - if (flags & mdnRejectSubsubDomains) { - // Check for sub-sub domain and reject - while(--hl >= 0 && h[hl] != '.'); - if (hl < 0) { - // No sub-sub domain found, but reject if there is a - // leading dot in given host string (which is removed - // before the check is started). - return hostIncludesSubdomains ? 1 : 0; - } else - return 1; // sub-sub domain, reject - } else - return 0; - } else - return 1; - } - } - - /* - * We found different characters in the same position (from the end). - */ - - // If the h has a form of "*.foo.com" and d has a form of "x.foo.com" - // then the h[hl] points to '*', h[hl+1] to '.' and d[dl] to 'x' - // The following checks are safe, the "h[hl + 1]" in the worst case is '\0'. - if ((flags & mdnHonorWildcards) && h[hl] == '*' && h[hl + 1] == '.') - return 0; - - /* - * If one of those character is '.' then its special. In order - * for splay tree sorting to work properly, "x-foo.com" must - * be greater than ".foo.com" even though '-' is less than '.'. - */ - if ('.' == d[dl]) - return 1; - - if ('.' == h[hl]) - return -1; - - return (xtolower(h[hl]) - xtolower(d[dl])); -} - -/* - * return true if we can serve requests for this method. - */ -int -urlCheckRequest(const HttpRequest * r) -{ - int rc = 0; - /* protocol "independent" methods - * - * actually these methods are specific to HTTP: - * they are methods we recieve on our HTTP port, - * and if we had a FTP listener would not be relevant - * there. - * - * So, we should delegate them to HTTP. The problem is that we - * do not have a default protocol from the client side of HTTP. - */ - - if (r->method == Http::METHOD_CONNECT) - return 1; - - // we support OPTIONS and TRACE directed at us (with a 501 reply, for now) - // we also support forwarding OPTIONS and TRACE, except for the *-URI ones - if (r->method == Http::METHOD_OPTIONS || r->method == Http::METHOD_TRACE) - return (r->header.getInt64(Http::HdrType::MAX_FORWARDS) == 0 || r->url.path() != URL::Asterisk()); - - if (r->method == Http::METHOD_PURGE) - return 1; - - /* does method match the protocol? */ - switch (r->url.getScheme()) { - - case AnyP::PROTO_URN: - - case AnyP::PROTO_HTTP: - - case AnyP::PROTO_CACHE_OBJECT: - rc = 1; - break; - - case AnyP::PROTO_FTP: - - if (r->method == Http::METHOD_PUT) - rc = 1; - - case AnyP::PROTO_GOPHER: - - case AnyP::PROTO_WAIS: - - case AnyP::PROTO_WHOIS: - if (r->method == Http::METHOD_GET) - rc = 1; - else if (r->method == Http::METHOD_HEAD) - rc = 1; - - break; - - case AnyP::PROTO_HTTPS: -#if USE_OPENSSL - rc = 1; -#elif USE_GNUTLS - rc = 1; -#else - /* - * Squid can't originate an SSL connection, so it should - * never receive an "https:" URL. It should always be - * CONNECT instead. - */ - rc = 0; -#endif - break; - - default: - break; - } - - return rc; -} - -/* - * Quick-n-dirty host extraction from a URL. Steps: - * Look for a colon - * Skip any '/' after the colon - * Copy the next SQUID_MAXHOSTNAMELEN bytes to host[] - * Look for an ending '/' or ':' and terminate - * Look for login info preceeded by '@' - */ - -class URLHostName -{ - -public: - char * extract(char const *url); - -private: - static char Host [SQUIDHOSTNAMELEN]; - void init(char const *); - void findHostStart(); - void trimTrailingChars(); - void trimAuth(); - char const *hostStart; - char const *url; -}; - -char * -urlHostname(const char *url) -{ - return URLHostName().extract(url); -} - -char URLHostName::Host[SQUIDHOSTNAMELEN]; - -void -URLHostName::init(char const *aUrl) -{ - Host[0] = '\0'; - url = aUrl; -} - -void -URLHostName::findHostStart() -{ - if (NULL == (hostStart = strchr(url, ':'))) - return; - - ++hostStart; - - while (*hostStart != '\0' && *hostStart == '/') - ++hostStart; - - if (*hostStart == ']') - ++hostStart; -} - -void -URLHostName::trimTrailingChars() -{ - char *t; - - if ((t = strchr(Host, '/'))) - *t = '\0'; - - if ((t = strrchr(Host, ':'))) - *t = '\0'; - - if ((t = strchr(Host, ']'))) - *t = '\0'; -} - -void -URLHostName::trimAuth() -{ - char *t; - - if ((t = strrchr(Host, '@'))) { - ++t; - memmove(Host, t, strlen(t) + 1); - } -} - -char * -URLHostName::extract(char const *aUrl) -{ - init(aUrl); - findHostStart(); - - if (hostStart == NULL) - return NULL; - - xstrncpy(Host, hostStart, SQUIDHOSTNAMELEN); - - trimTrailingChars(); - - trimAuth(); - - return Host; -} - -URL::URL(AnyP::UriScheme const &aScheme) : - scheme_(aScheme), - hostIsNumeric_(false), - port_(0) -{ - *host_=0; -} - diff -u -r -N squid-4.0.25/src/URL.h squid-4.1/src/URL.h --- squid-4.0.25/src/URL.h 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/URL.h 1970-01-01 12:00:00.000000000 +1200 @@ -1,225 +0,0 @@ -/* - * Copyright (C) 1996-2018 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -#ifndef SQUID_SRC_URL_H -#define SQUID_SRC_URL_H - -#include "anyp/UriScheme.h" -#include "ip/Address.h" -#include "rfc2181.h" -#include "sbuf/SBuf.h" - -#include - -/** - * The URL class represents a Uniform Resource Location - * - * Governed by RFC 3986 - */ -class URL -{ - MEMPROXY_CLASS(URL); - -public: - URL() : hostIsNumeric_(false), port_(0) {*host_=0;} - URL(AnyP::UriScheme const &aScheme); - URL(const URL &other) { - this->operator =(other); - } - URL &operator =(const URL &o) { - scheme_ = o.scheme_; - userInfo_ = o.userInfo_; - memcpy(host_, o.host_, sizeof(host_)); - hostIsNumeric_ = o.hostIsNumeric_; - hostAddr_ = o.hostAddr_; - port_ = o.port_; - path_ = o.path_; - touch(); - return *this; - } - - void clear() { - scheme_=AnyP::PROTO_NONE; - hostIsNumeric_ = false; - *host_ = 0; - hostAddr_.setEmpty(); - port_ = 0; - touch(); - } - void touch(); ///< clear the cached URI display forms - - bool parse(const HttpRequestMethod &, const char *url); - - AnyP::UriScheme const & getScheme() const {return scheme_;} - - /// convert the URL scheme to that given - void setScheme(const AnyP::ProtocolType &p, const char *str) { - scheme_ = AnyP::UriScheme(p, str); - touch(); - } - - void userInfo(const SBuf &s) {userInfo_=s; touch();} - const SBuf &userInfo() const {return userInfo_;} - - void host(const char *src); - const char *host(void) const {return host_;} - int hostIsNumeric(void) const {return hostIsNumeric_;} - Ip::Address const & hostIP(void) const {return hostAddr_;} - - void port(unsigned short p) {port_=p; touch();} - unsigned short port() const {return port_;} - - void path(const char *p) {path_=p; touch();} - void path(const SBuf &p) {path_=p; touch();} - const SBuf &path() const; - - /// the static '/' default URL-path - static const SBuf &SlashPath(); - - /// the static '*' pseudo-URL - static const SBuf &Asterisk(); - - /** - * The authority-form URI for currently stored values. - * - * As defined by RFC 7230 section 5.3.3 this form omits the - * userinfo@ field from RFC 3986 defined authority segment. - * - * \param requirePort when true the port will be included, otherwise - * port will be elided when it is the default for - * the current scheme. - */ - SBuf &authority(bool requirePort = false) const; - - /** - * The absolute-form URI for currently stored values. - * - * As defined by RFC 7230 section 5.3.3 this form omits the - * userinfo@ field from RFC 3986 defined authority segments - * when the protocol scheme is http: or https:. - */ - SBuf &absolute() const; - -private: - void parseFinish(const AnyP::ProtocolType, const char *const, const char *const, const char *const, const SBuf &, const int); - - /** - \par - * The scheme of this URL. This has the 'type code' smell about it. - * In future we may want to make the methods that dispatch based on - * the scheme virtual and have a class per protocol. - \par - * On the other hand, having Protocol as an explicit concept is useful, - * see for instance the ACLProtocol acl type. One way to represent this - * is to have one prototype URL with no host etc for each scheme, - * another is to have an explicit scheme class, and then each URL class - * could be a subclass of the scheme. Another way is one instance of - * a AnyP::UriScheme class instance for each URL scheme we support, and one URL - * class for each manner of treating the scheme : a Hierarchical URL, a - * non-hierarchical URL etc. - \par - * Deferring the decision, its a type code for now. RBC 20060507. - \par - * In order to make taking any of these routes easy, scheme is private - * and immutable, only settable at construction time, - */ - AnyP::UriScheme scheme_; - - SBuf userInfo_; // aka 'URL-login' - - // XXX: uses char[] instead of SBUf to reduce performance regressions - // from c_str() since most code using this is not yet using SBuf - char host_[SQUIDHOSTNAMELEN]; ///< string representation of the URI authority name or IP - bool hostIsNumeric_; ///< whether the authority 'host' is a raw-IP - Ip::Address hostAddr_; ///< binary representation of the URI authority if it is a raw-IP - - unsigned short port_; ///< URL port - - // XXX: for now includes query-string. - SBuf path_; ///< URL path segment - - // pre-assembled URL forms - mutable SBuf authorityHttp_; ///< RFC 7230 section 5.3.3 authority, maybe without default-port - mutable SBuf authorityWithPort_; ///< RFC 7230 section 5.3.3 authority with explicit port - mutable SBuf absolute_; ///< RFC 7230 section 5.3.2 absolute-URI -}; - -inline std::ostream & -operator <<(std::ostream &os, const URL &url) -{ - // none means explicit empty string for scheme. - if (url.getScheme() != AnyP::PROTO_NONE) - os << url.getScheme().image(); - os << ":"; - - // no authority section on URN - if (url.getScheme() != AnyP::PROTO_URN) - os << "//" << url.authority(); - - // path is what it is - including absent - os << url.path(); - return os; -} - -class HttpRequest; -class HttpRequestMethod; - -void urlInitialize(void); -char *urlCanonicalClean(const HttpRequest *); -const char *urlCanonicalFakeHttps(const HttpRequest * request); -bool urlIsRelative(const char *); -char *urlMakeAbsolute(const HttpRequest *, const char *); -char *urlRInternal(const char *host, unsigned short port, const char *dir, const char *name); -char *urlInternal(const char *dir, const char *name); - -enum MatchDomainNameFlags { - mdnNone = 0, - mdnHonorWildcards = 1 << 0, - mdnRejectSubsubDomains = 1 << 1 -}; - -/** - * matchDomainName() matches a hostname (usually extracted from traffic) - * with a domainname when mdnNone or mdnRejectSubsubDomains flags are used - * according to the following rules: - * - * HOST | DOMAIN | mdnNone | mdnRejectSubsubDomains - * -------------|-------------|-----------|----------------------- - * foo.com | foo.com | YES | YES - * .foo.com | foo.com | YES | YES - * x.foo.com | foo.com | NO | NO - * foo.com | .foo.com | YES | YES - * .foo.com | .foo.com | YES | YES - * x.foo.com | .foo.com | YES | YES - * .x.foo.com | .foo.com | YES | NO - * y.x.foo.com | .foo.com | YES | NO - * - * if mdnHonorWildcards flag is set then the matchDomainName() also accepts - * optional wildcards on hostname: - * - * HOST | DOMAIN | MATCH? - * -------------|--------------|------- - * *.foo.com | x.foo.com | YES - * *.foo.com | .x.foo.com | YES - * *.foo.com | .foo.com | YES - * *.foo.com | foo.com | NO - * - * The combination of mdnHonorWildcards and mdnRejectSubsubDomains flags is - * supported. - * - * \retval 0 means the host matches the domain - * \retval 1 means the host is greater than the domain - * \retval -1 means the host is less than the domain - */ -int matchDomainName(const char *host, const char *domain, uint flags = mdnNone); -int urlCheckRequest(const HttpRequest *); -char *urlHostname(const char *url); -void urlExtMethodConfigure(void); - -#endif /* SQUID_SRC_URL_H_H */ - diff -u -r -N squid-4.0.25/src/urn.cc squid-4.1/src/urn.cc --- squid-4.0.25/src/urn.cc 2018-06-12 04:30:57.000000000 +1200 +++ squid-4.1/src/urn.cc 2018-07-02 15:26:07.000000000 +1200 @@ -23,7 +23,6 @@ #include "Store.h" #include "StoreClient.h" #include "tools.h" -#include "URL.h" #include "urn.h" #define URN_REQBUF_SZ 4096 @@ -145,7 +144,7 @@ } SBuf uri = r->url.path(); - // TODO: use class URL instead of generating a string and re-parsing + // TODO: use class AnyP::Uri instead of generating a string and re-parsing LOCAL_ARRAY(char, local_urlres, 4096); char *host = getHost(uri); snprintf(local_urlres, 4096, "http://%s/uri-res/N2L?urn:" SQUIDSBUFPH, host, SQUIDSBUFPRINT(uri)); diff -u -r -N squid-4.0.25/tools/helper-mux/helper-mux.8 squid-4.1/tools/helper-mux/helper-mux.8 --- squid-4.0.25/tools/helper-mux/helper-mux.8 2018-06-12 04:56:22.000000000 +1200 +++ squid-4.1/tools/helper-mux/helper-mux.8 2018-07-02 15:39:09.000000000 +1200 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "HELPER-MUX 8" -.TH HELPER-MUX 8 "2018-06-11" "perl v5.26.2" "User Contributed Perl Documentation" +.TH HELPER-MUX 8 "2018-07-02" "perl v5.26.2" "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