Пример #1
0
 protected function doNotify($channel, array $events)
 {
     if (!count($events)) {
         return true;
     }
     $response = $this->http->run(array('url' => "{$this->baseUrl}/relayer/api/v1.0/" . rawurlencode($channel), 'method' => 'POST', 'body' => json_encode(array('events' => $events)), 'headers' => array('content-type' => 'application/json')));
     return $response['code'] == 201;
 }
 /**
  * Runs all the queries.
  */
 public function run()
 {
     $http = new MultiHttpClient(array('reqTimeout' => $this->timeout, 'connTimeout' => 3));
     $responses = $http->runMulti($this->getMultiHttpQueries($this->queries));
     foreach ($responses as $index => $response) {
         $this->responses[$index] = $response;
     }
     $this->hasRun = true;
 }
Пример #3
0
 /**
  * Delete an item.
  *
  * @param string $key
  * @return bool True if the item was deleted or not found, false on failure
  */
 public function delete($key)
 {
     $req = ['method' => 'DELETE', 'url' => $this->url . rawurlencode($key)];
     list($rcode, $rdesc, $rhdrs, $rbody, $rerr) = $this->client->run($req);
     if ($rcode === 200 || $rcode === 204 || $rcode === 205) {
         return true;
     }
     return $this->handleError("Failed to delete {$key}", $rcode, $rerr);
 }
Пример #4
0
 /**
  * @return array|null Credential map
  */
 protected function getAuthentication()
 {
     if ($this->authErrorTimestamp !== null) {
         if (time() - $this->authErrorTimestamp < 60) {
             return null;
             // failed last attempt; don't bother
         } else {
             // actually retry this time
             $this->authErrorTimestamp = null;
         }
     }
     // Session keys expire after a while, so we renew them periodically
     $reAuth = time() - $this->authSessionTimestamp > $this->authTTL;
     // Authenticate with proxy and get a session key...
     if (!$this->authCreds || $reAuth) {
         $this->authSessionTimestamp = 0;
         $cacheKey = $this->getCredsCacheKey($this->swiftUser);
         $creds = $this->srvCache->get($cacheKey);
         // credentials
         // Try to use the credential cache
         if (isset($creds['auth_token']) && isset($creds['storage_url'])) {
             $this->authCreds = $creds;
             // Skew the timestamp for worst case to avoid using stale credentials
             $this->authSessionTimestamp = time() - ceil($this->authTTL / 2);
         } else {
             // cache miss
             list($rcode, $rdesc, $rhdrs, $rbody, $rerr) = $this->http->run(array('method' => 'GET', 'url' => "{$this->swiftAuthUrl}/v1.0", 'headers' => array('x-auth-user' => $this->swiftUser, 'x-auth-key' => $this->swiftKey)));
             if ($rcode >= 200 && $rcode <= 299) {
                 // OK
                 $this->authCreds = array('auth_token' => $rhdrs['x-auth-token'], 'storage_url' => $rhdrs['x-storage-url']);
                 $this->srvCache->set($cacheKey, $this->authCreds, ceil($this->authTTL / 2));
                 $this->authSessionTimestamp = time();
             } elseif ($rcode === 401) {
                 $this->onError(null, __METHOD__, array(), "Authentication failed.", $rcode);
                 $this->authErrorTimestamp = time();
                 return null;
             } else {
                 $this->onError(null, __METHOD__, array(), "HTTP return code: {$rcode}", $rcode);
                 $this->authErrorTimestamp = time();
                 return null;
             }
         }
         // Ceph RGW does not use <account> in URLs (OpenStack Swift uses "/v1/<account>")
         if (substr($this->authCreds['storage_url'], -3) === '/v1') {
             $this->isRGW = true;
             // take advantage of strong consistency in Ceph
         }
     }
     return $this->authCreds;
 }
 /**
  * Execute a set of virtual HTTP(S) requests concurrently
  *
  * A map of requests keys to response maps is returned. Each response map has:
  *   - code    : HTTP response code or 0 if there was a serious cURL error
  *   - reason  : HTTP response reason (empty if there was a serious cURL error)
  *   - headers : <header name/value associative array>
  *   - body    : HTTP response body or resource (if "stream" was set)
  *   - error   : Any cURL error string
  * The map also stores integer-indexed copies of these values. This lets callers do:
  * @code
  *     list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $responses[0];
  * @endcode
  *
  * @param array $reqs Map of Virtual HTTP request maps
  * @return array $reqs Map of corresponding response values with the same keys/order
  * @throws Exception
  */
 public function runMulti(array $reqs)
 {
     foreach ($reqs as $index => &$req) {
         if (isset($req[0])) {
             $req['method'] = $req[0];
             // short-form
             unset($req[0]);
         }
         if (isset($req[1])) {
             $req['url'] = $req[1];
             // short-form
             unset($req[1]);
         }
         $req['chain'] = [];
         // chain or list of replaced requests
     }
     unset($req);
     // don't assign over this by accident
     $curUniqueId = 0;
     $armoredIndexMap = [];
     // (original index => new index)
     $doneReqs = [];
     // (index => request)
     $executeReqs = [];
     // (index => request)
     $replaceReqsByService = [];
     // (prefix => index => request)
     $origPending = [];
     // (index => 1) for original requests
     foreach ($reqs as $origIndex => $req) {
         // Re-index keys to consecutive integers (they will be swapped back later)
         $index = $curUniqueId++;
         $armoredIndexMap[$origIndex] = $index;
         $origPending[$index] = 1;
         if (preg_match('#^(http|ftp)s?://#', $req['url'])) {
             // Absolute FTP/HTTP(S) URL, run it as normal
             $executeReqs[$index] = $req;
         } else {
             // Must be a virtual HTTP URL; resolve it
             list($prefix, $service) = $this->getMountAndService($req['url']);
             if (!$service) {
                 throw new UnexpectedValueException("Path '{$req['url']}' has no service.");
             }
             // Set the URL to the mount-relative portion
             $req['url'] = substr($req['url'], strlen($prefix));
             $replaceReqsByService[$prefix][$index] = $req;
         }
     }
     // Function to get IDs that won't collide with keys in $armoredIndexMap
     $idFunc = function () use(&$curUniqueId) {
         return $curUniqueId++;
     };
     $rounds = 0;
     do {
         if (++$rounds > 5) {
             // sanity
             throw new Exception("Too many replacement rounds detected. Aborting.");
         }
         // Track requests executed this round that have a prefix/service.
         // Note that this also includes requests where 'response' was forced.
         $checkReqIndexesByPrefix = [];
         // Resolve the virtual URLs valid and qualified HTTP(S) URLs
         // and add any required authentication headers for the backend.
         // Services can also replace requests with new ones, either to
         // defer the original or to set a proxy response to the original.
         $newReplaceReqsByService = [];
         foreach ($replaceReqsByService as $prefix => $servReqs) {
             $service = $this->instances[$prefix];
             foreach ($service->onRequests($servReqs, $idFunc) as $index => $req) {
                 // Services use unique IDs for replacement requests
                 if (isset($servReqs[$index]) || isset($origPending[$index])) {
                     // A current or original request which was not modified
                 } else {
                     // Replacement request that will convert to original requests
                     $newReplaceReqsByService[$prefix][$index] = $req;
                 }
                 if (isset($req['response'])) {
                     // Replacement requests with pre-set responses should not execute
                     unset($executeReqs[$index]);
                     unset($origPending[$index]);
                     $doneReqs[$index] = $req;
                 } else {
                     // Original or mangled request included
                     $executeReqs[$index] = $req;
                 }
                 $checkReqIndexesByPrefix[$prefix][$index] = 1;
             }
         }
         // Update index of requests to inspect for replacement
         $replaceReqsByService = $newReplaceReqsByService;
         // Run the actual work HTTP requests
         foreach ($this->http->runMulti($executeReqs) as $index => $ranReq) {
             $doneReqs[$index] = $ranReq;
             unset($origPending[$index]);
         }
         $executeReqs = [];
         // Services can also replace requests with new ones, either to
         // defer the original or to set a proxy response to the original.
         // Any replacement requests executed above will need to be replaced
         // with new requests (eventually the original). The responses can be
         // forced by setting 'response' rather than actually be sent over the wire.
         $newReplaceReqsByService = [];
         foreach ($checkReqIndexesByPrefix as $prefix => $servReqIndexes) {
             $service = $this->instances[$prefix];
             // $doneReqs actually has the requests (with 'response' set)
             $servReqs = array_intersect_key($doneReqs, $servReqIndexes);
             foreach ($service->onResponses($servReqs, $idFunc) as $index => $req) {
                 // Services use unique IDs for replacement requests
                 if (isset($servReqs[$index]) || isset($origPending[$index])) {
                     // A current or original request which was not modified
                 } else {
                     // Replacement requests with pre-set responses should not execute
                     $newReplaceReqsByService[$prefix][$index] = $req;
                 }
                 if (isset($req['response'])) {
                     // Replacement requests with pre-set responses should not execute
                     unset($origPending[$index]);
                     $doneReqs[$index] = $req;
                 } else {
                     // Update the request in case it was mangled
                     $executeReqs[$index] = $req;
                 }
             }
         }
         // Update index of requests to inspect for replacement
         $replaceReqsByService = $newReplaceReqsByService;
     } while (count($origPending));
     $responses = [];
     // Update $reqs to include 'response' and normalized request 'headers'.
     // This maintains the original order of $reqs.
     foreach ($reqs as $origIndex => $req) {
         $index = $armoredIndexMap[$origIndex];
         if (!isset($doneReqs[$index])) {
             throw new UnexpectedValueException("Response for request '{$index}' is NULL.");
         }
         $responses[$origIndex] = $doneReqs[$index]['response'];
     }
     return $responses;
 }
Пример #6
0
 public function testDelete()
 {
     $this->client->expects($this->once())->method('run')->with(['method' => 'DELETE', 'url' => 'http://test/rest/42xyz42'])->willReturn([200, 'OK', [], 'Done', 0]);
     $result = $this->bag->delete('42xyz42');
     $this->assertTrue($result);
 }