Ampache PHP Cross Reference Groupware Applications

Source: /modules/Dropbox/RequestUtil.php - 252 lines - 8212 bytes - Summary - Text - Print

   1  <?php
   2  namespace Dropbox;
   3  
   4  if (!function_exists('curl_init')) {
   5      throw new \Exception("The Dropbox SDK requires the cURL PHP extension, but it looks like you don't have it (couldn't find function \"curl_init\").  Library: \"" . __FILE__ . "\".");
   6  }
   7  
   8  if (!function_exists('json_decode')) {
   9      throw new \Exception("The Dropbox SDK requires the JSON PHP extension, but it looks like you don't have it (couldn't find function \"json_decode\").  Library: \"" . __FILE__ . "\".");
  10  }
  11  
  12  if (strlen((string) PHP_INT_MAX) < 19) {
  13      // Looks like we're running on a 32-bit build of PHP.  This could cause problems because some of the numbers
  14      // we use (file sizes, quota, etc) can be larger than 32-bit ints can handle.
  15      //throw new \Exception("The Dropbox SDK uses 64-bit integers, but it looks like we're running on a version of PHP that doesn't support 64-bit integers (PHP_INT_MAX=" . ((string) PHP_INT_MAX) . ").  Library: \"" . __FILE__ . "\"");
  16  }
  17  
  18  /**
  19   * @internal
  20   */
  21  final class RequestUtil
  22  {
  23      /**
  24       * @param string $userLocale
  25       * @param string $host
  26       * @param string $path
  27       * @param array $params
  28       * @return string
  29       */
  30      static function buildUrl($userLocale, $host, $path, $params = null)
  31      {
  32          $url = self::buildUri($host, $path);
  33          $url .= "?locale=" . rawurlencode($userLocale);
  34  
  35          if ($params !== null) {
  36              foreach ($params as $key => $value) {
  37                  Checker::argStringNonEmpty("key in 'params'", $key);
  38                  if ($value !== null) {
  39                      if (is_bool($value)) {
  40                          $value = $value ? "true" : "false";
  41                      }
  42                      else if (is_int($value)) {
  43                          $value = (string) $value;
  44                      }
  45                      else if (!is_string($value)) {
  46                          throw new \InvalidArgumentException("params['$key'] is not a string, int, or bool");
  47                      }
  48                      $url .= "&" . rawurlencode($key) . "=" . rawurlencode($value);
  49                  }
  50              }
  51          }
  52          return $url;
  53      }
  54  
  55      /**
  56       * @param string $host
  57       * @param string $path
  58       * @return string
  59       */
  60      static function buildUri($host, $path)
  61      {
  62          Checker::argStringNonEmpty("host", $host);
  63          Checker::argStringNonEmpty("path", $path);
  64          return "https://" . $host . "/" . $path;
  65      }
  66  
  67      /**
  68       * @param string $clientIdentifier
  69       * @param string $url
  70       * @return Curl
  71       */
  72      static function mkCurlWithoutAuth($clientIdentifier, $url, $maxsize=0)
  73      {
  74          $curl = new Curl($url, $maxsize);
  75  
  76          $curl->set(CURLOPT_CONNECTTIMEOUT, 10);
  77  
  78          // If the transfer speed is below 1kB/sec for 10 sec, abort.
  79          $curl->set(CURLOPT_LOW_SPEED_LIMIT, 1024);
  80          $curl->set(CURLOPT_LOW_SPEED_TIME, 10);
  81  
  82          //$curl->set(CURLOPT_VERBOSE, true);  // For debugging.
  83          // TODO: Figure out how to encode clientIdentifier (urlencode?)
  84          $curl->addHeader("User-Agent: ".$clientIdentifier." Dropbox-PHP-SDK");
  85  
  86          return $curl;
  87      }
  88  
  89      /**
  90       * @param string $clientIdentifier
  91       * @param string $url
  92       * @param string $accessToken
  93       * @return Curl
  94       */
  95      static function mkCurl($clientIdentifier, $url, $accessToken, $maxsize=0)
  96      {
  97          $curl = self::mkCurlWithoutAuth($clientIdentifier, $url, $maxsize);
  98          $curl->addHeader("Authorization: Bearer $accessToken");
  99          return $curl;
 100      }
 101  
 102      static function buildPostBody($params)
 103      {
 104          if ($params === null) return "";
 105  
 106          $pairs = array();
 107          foreach ($params as $key => $value) {
 108              Checker::argStringNonEmpty("key in 'params'", $key);
 109              if ($value !== null) {
 110                  if (is_bool($value)) {
 111                      $value = $value ? "true" : "false";
 112                  }
 113                  else if (is_int($value)) {
 114                      $value = (string) $value;
 115                  }
 116                  else if (!is_string($value)) {
 117                      throw new \InvalidArgumentException("params['$key'] is not a string, int, or bool");
 118                  }
 119                  $pairs[] = rawurlencode($key) . "=" . rawurlencode((string) $value);
 120              }
 121          }
 122          return implode("&", $pairs);
 123      }
 124  
 125      /**
 126       * @param string $accessToken
 127       * @param string $userLocale
 128       * @param string $host
 129       * @param string $path
 130       * @param array|null $params
 131       *
 132       * @return HttpResponse
 133       *
 134       * @throws Exception
 135       */
 136      static function doPost($clientIdentifier, $accessToken, $userLocale, $host, $path, $params = null)
 137      {
 138          Checker::argStringNonEmpty("accessToken", $accessToken);
 139  
 140          $url = self::buildUri($host, $path);
 141  
 142          if ($params === null) $params = array();
 143          $params['locale'] = $userLocale;
 144  
 145          $curl = self::mkCurl($clientIdentifier, $url, $accessToken);
 146          $curl->set(CURLOPT_POST, true);
 147          $curl->set(CURLOPT_POSTFIELDS, self::buildPostBody($params));
 148  
 149          $curl->set(CURLOPT_RETURNTRANSFER, true);
 150          return $curl->exec();
 151      }
 152  
 153      /**
 154       * @param string $accessToken
 155       * @param string $userLocale
 156       * @param string $host
 157       * @param string $path
 158       * @param array|null $params
 159       *
 160       * @return HttpResponse
 161       *
 162       * @throws Exception
 163       */
 164      static function doGet($clientIdentifier, $accessToken, $userLocale, $host, $path, $params = null)
 165      {
 166          Checker::argStringNonEmpty("accessToken", $accessToken);
 167  
 168          $url = self::buildUrl($userLocale, $host, $path, $params);
 169  
 170          $curl = self::mkCurl($clientIdentifier, $url, $accessToken);
 171          $curl->set(CURLOPT_HTTPGET, true);
 172          $curl->set(CURLOPT_RETURNTRANSFER, true);
 173  
 174          return $curl->exec();
 175      }
 176  
 177      /**
 178       * @param string $responseBody
 179       * @return mixed
 180       * @throws Exception_BadResponse
 181       */
 182      static function parseResponseJson($responseBody)
 183      {
 184          $obj = json_decode($responseBody, TRUE, 10);
 185          if ($obj === null) {
 186              throw new Exception_BadResponse("Got bad JSON from server: $responseBody");
 187          }
 188          return $obj;
 189      }
 190  
 191      static function unexpectedStatus($httpResponse)
 192      {
 193          $sc = $httpResponse->statusCode;
 194  
 195          $message = "HTTP status $sc";
 196          if (is_string($httpResponse->body)) {
 197              // TODO: Maybe only include the first ~200 chars of the body?
 198              $message .= "\n".$httpResponse->body;
 199          }
 200  
 201          if ($sc === 400) return new Exception_BadRequest($message);
 202          if ($sc === 401) return new Exception_InvalidAccessToken($message);
 203          if ($sc === 500 || $sc === 502) return new Exception_ServerError($message);
 204          if ($sc === 503) return new Exception_RetryLater($message);
 205  
 206          return new Exception_BadResponse("Unexpected $message");
 207      }
 208  
 209      /**
 210       * @param int $maxRetries
 211       *    The number of times to retry it the action if it fails with one of the transient
 212       *    API errors.  A value of 1 means we'll try the action once and if it fails, we
 213       *    will retry once.
 214       *
 215       * @param callable $action
 216       *    The the action you want to retry.
 217       *
 218       * @return mixed
 219       *    Whatever is returned by the $action callable.
 220       */
 221      static function runWithRetry($maxRetries, $action)
 222      {
 223          Checker::argNat("maxRetries", $maxRetries);
 224  
 225          $retryDelay = 1;
 226          $numRetries = 0;
 227          while (true) {
 228              try {
 229                  return $action();
 230              }
 231              // These exception types are the ones we think are possibly transient errors.
 232              catch (Exception_NetworkIO $ex) {
 233                  $savedEx = $ex;
 234              }
 235              catch (Exception_ServerError $ex) {
 236                  $savedEx = $ex;
 237              }
 238              catch (Exception_RetryLater $ex) {
 239                  $savedEx = $ex;
 240              }
 241  
 242              // We maxed out our retries.  Propagate the last exception we got.
 243              if ($numRetries >= $maxRetries) throw $savedEx;
 244  
 245              $numRetries++;
 246              sleep($retryDelay);
 247              $retryDelay *= 2;  // Exponential back-off.
 248          }
 249          throw new \RuntimeException("unreachable");
 250      }
 251  
 252  }

title

Description

title

Description

title

Description

title

title

Body