/**
  * @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;
     }
 }
Beispiel #2
0
 /**
  * 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']);
         }
     }
 }