From edd81d2a5dd0134655f99d3938a22a8fcdc8f379 Mon Sep 17 00:00:00 2001 From: Catrope Date: Fri, 6 Apr 2012 13:27:10 -0700 Subject: [PATCH] Implement routing for HTCP purges This allows HTCP purges for different domains to be sent to different multicast groups, based on regexes. Mark requested this so we could separate the multicast groups for upload caches and text caches. This code is UNTESTED, I'm mostly submitting this as a proof of concept and to invite review by other core devs (specifically Tim). Change-Id: Ie333a04131d6ca8394884ed1054f2baff55ab2d1 --- includes/DefaultSettings.php | 37 +++++++++++++++++++++++++++++++++- includes/Setup.php | 10 +++++++++ includes/cache/SquidUpdate.php | 32 +++++++++++++++++++++++++---- 3 files changed, 74 insertions(+), 5 deletions(-) diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index 8402d698d3..48995a4788 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -1861,23 +1861,58 @@ $wgSquidServersNoPurge = array(); /** Maximum number of titles to purge in any one client operation */ $wgMaxSquidPurgeTitles = 400; +/** + * Routing configuration for HTCP multicast purging. Add elements here to + * enable HTCP and determine which purges are sent where. If set to an empty + * array, HTCP is disabled. + * + * Each key in this array is a regular expression to match against the purged + * URL, or an empty string to match all URLs. The purged URL is matched against + * the regexes in the order specified, and the first rule whose regex matches + * is used. + * + * Example configuration to send purges for upload.wikimedia.org to one + * multicast group and all other purges to another: + * $wgHTCPMulticastRouting = array( + * '|^https?://upload\.wikimedia\.org|' => array( + * 'host' => '239.128.0.113', + * 'port' => 4827, + * ), + * '' => array( + * 'host' => '239.128.0.112', + * 'port' => 4827, + * ), + * ); + * + * @see $wgHTCPMulticastTTL + */ +$wgHTCPMulticastRouting = array(); + /** * HTCP multicast address. Set this to a multicast IP address to enable HTCP. * * Note that MediaWiki uses the old non-RFC compliant HTCP format, which was * present in the earliest Squid implementations of the protocol. + * + * This setting is DEPRECATED in favor of $wgHTCPMulticastRouting , and kept + * for backwards compatibility only. If $wgHTCPMulticastRouting is set, this + * setting is ignored. If $wgHTCPMulticastRouting is not set and this setting + * is, it is used to populate $wgHTCPMulticastRouting. + * + * @deprecated in favor of $wgHTCPMulticastRouting */ $wgHTCPMulticastAddress = false; /** * HTCP multicast port. + * @deprecated in favor of $wgHTCPMulticastRouting * @see $wgHTCPMulticastAddress */ $wgHTCPPort = 4827; /** * HTCP multicast TTL. - * @see $wgHTCPMulticastAddress + * @see $wgHTCPMulticastRouting */ $wgHTCPMulticastTTL = 1; diff --git a/includes/Setup.php b/includes/Setup.php index 2777f73296..9333e40786 100644 --- a/includes/Setup.php +++ b/includes/Setup.php @@ -391,6 +391,16 @@ if ( $wgCanonicalServer === false ) { $wgCanonicalServer = wfExpandUrl( $wgServer, PROTO_HTTP ); } +// Initialize $wgHTCPMulticastRouting from backwards-compatible settings +if ( !$wgHTCPMulticastRouting && $wgHTCPMulticastAddress ) { + $wgHTCPMulticastRouting = array( + '' => array( + 'host' => $wgHTCPMulticastAddress, + 'port' => $wgHTCPPort, + ) + ); +} + wfProfileIn( $fname . '-misc1' ); # Raise the memory limit if it's too low diff --git a/includes/cache/SquidUpdate.php b/includes/cache/SquidUpdate.php index bd70095b84..e560e0e7db 100644 --- a/includes/cache/SquidUpdate.php +++ b/includes/cache/SquidUpdate.php @@ -103,7 +103,7 @@ class SquidUpdate { * @return void */ static function purge( $urlArr ) { - global $wgSquidServers, $wgHTCPMulticastAddress, $wgHTCPPort; + global $wgSquidServers, $wgHTCPMulticastRouting; /*if ( (@$wgSquidServers[0]) == 'echo' ) { echo implode("
\n", $urlArr) . "
\n"; @@ -114,7 +114,7 @@ class SquidUpdate { return; } - if ( $wgHTCPMulticastAddress && $wgHTCPPort ) { + if ( $wgHTCPMulticastRouting ) { SquidUpdate::HTCPPurge( $urlArr ); } @@ -149,7 +149,7 @@ class SquidUpdate { * @param $urlArr array */ static function HTCPPurge( $urlArr ) { - global $wgHTCPMulticastAddress, $wgHTCPMulticastTTL, $wgHTCPPort; + global $wgHTCPMulticastRouting, $wgHTCPMulticastTTL; wfProfileIn( __METHOD__ ); $htcpOpCLR = 4; // HTCP CLR @@ -176,6 +176,14 @@ class SquidUpdate { throw new MWException( 'Bad purge URL' ); } $url = SquidUpdate::expand( $url ); + $conf = self::getRuleForURL( $url, $wgHTCPMulticastRouting ); + if ( !$conf ) { + wfDebug( "No HTCP rule configured for URL $url , skipping\n" ); + continue; + } + if ( !isset( $conf['host'] ) || !isset( $conf['port'] ) ) { + throw new MWException( "Invalid HTCP rule for URL $url\n" ); + } // Construct a minimal HTCP request diagram // as per RFC 2756 @@ -199,7 +207,7 @@ class SquidUpdate { // Send out wfDebug( "Purging URL $url via HTCP\n" ); socket_sendto( $conn, $htcpPacket, $htcpLen, 0, - $wgHTCPMulticastAddress, $wgHTCPPort ); + $conf['host'], $conf['port'] ); } } else { $errstr = socket_strerror( socket_last_error() ); @@ -226,4 +234,20 @@ class SquidUpdate { static function expand( $url ) { return wfExpandUrl( $url, PROTO_INTERNAL ); } + + /** + * Find the HTCP routing rule to use for a given URL. + * @param $url string URL to match + * @param $rules array Array of rules, see $wgHTCPMulticastRouting for format and behavior + * @return mixed Element of $rules that matched, or false if nothing matched + */ + static function getRuleForURL( $url, $rules ) { + foreach ( $rules as $regex => $routing ) { + if ( $regex === '' || preg_match( $regex, $url ) ) { + return $routing; + } + } + return false; + } + } -- 2.20.1