/** * @covers UIDGenerator::newSequentialPerNodeIDs */ public function testNewSequentialIDs() { $ids = UIDGenerator::newSequentialPerNodeIDs('test', 32, 5); $lastId = null; foreach ($ids as $id) { $this->assertType('float', $id, "ID returned as float"); $this->assertGreaterThan(0, $id, "ID greater than 1"); if ($lastId) { $this->assertGreaterThan($lastId, $id, "IDs increasing in value"); } $lastId = $id; } }
/** * Send Hyper Text Caching Protocol (HTCP) CLR requests. * * @throws MWException * @param string[] $urlArr Collection of URLs to purge */ private static function HTCPPurge(array $urlArr) { global $wgHTCPRouting, $wgHTCPMulticastTTL; // HTCP CLR operation $htcpOpCLR = 4; // @todo FIXME: PHP doesn't support these socket constants (include/linux/in.h) if (!defined("IPPROTO_IP")) { define("IPPROTO_IP", 0); define("IP_MULTICAST_LOOP", 34); define("IP_MULTICAST_TTL", 33); } // pfsockopen doesn't work because we need set_sock_opt $conn = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); if (!$conn) { $errstr = socket_strerror(socket_last_error()); wfDebugLog('squid', __METHOD__ . ": Error opening UDP socket: {$errstr}"); return; } // Set socket options socket_set_option($conn, IPPROTO_IP, IP_MULTICAST_LOOP, 0); if ($wgHTCPMulticastTTL != 1) { // Set multicast time to live (hop count) option on socket socket_set_option($conn, IPPROTO_IP, IP_MULTICAST_TTL, $wgHTCPMulticastTTL); } // Get sequential trx IDs for packet loss counting $ids = UIDGenerator::newSequentialPerNodeIDs('squidhtcppurge', 32, count($urlArr), UIDGenerator::QUICK_VOLATILE); foreach ($urlArr as $url) { if (!is_string($url)) { throw new MWException('Bad purge URL'); } $url = self::expand($url); $conf = self::getRuleForURL($url, $wgHTCPRouting); if (!$conf) { wfDebugLog('squid', __METHOD__ . "No HTCP rule configured for URL {$url} , skipping"); continue; } if (isset($conf['host']) && isset($conf['port'])) { // Normalize single entries $conf = array($conf); } foreach ($conf as $subconf) { if (!isset($subconf['host']) || !isset($subconf['port'])) { throw new MWException("Invalid HTCP rule for URL {$url}\n"); } } // Construct a minimal HTCP request diagram // as per RFC 2756 // Opcode 'CLR', no response desired, no auth $htcpTransID = current($ids); next($ids); $htcpSpecifier = pack('na4na*na8n', 4, 'HEAD', strlen($url), $url, 8, 'HTTP/1.0', 0); $htcpDataLen = 8 + 2 + strlen($htcpSpecifier); $htcpLen = 4 + $htcpDataLen + 2; // Note! Squid gets the bit order of the first // word wrong, wrt the RFC. Apparently no other // implementation exists, so adapt to Squid $htcpPacket = pack('nxxnCxNxxa*n', $htcpLen, $htcpDataLen, $htcpOpCLR, $htcpTransID, $htcpSpecifier, 2); wfDebugLog('squid', __METHOD__ . "Purging URL {$url} via HTCP"); foreach ($conf as $subconf) { socket_sendto($conn, $htcpPacket, $htcpLen, 0, $subconf['host'], $subconf['port']); } } }