From 35402cfea814bd8144b1a04654010748689bfce5 Mon Sep 17 00:00:00 2001 From: andyexeter Date: Thu, 9 May 2019 11:28:40 +0100 Subject: [PATCH] Fix new resource rate limit issue --- lib/CurlRequest.php | 32 ++++++--- lib/CurlResponse.php | 73 ++++++++++++++++++++ lib/Exception/ResourceRateLimitException.php | 8 +++ 3 files changed, 103 insertions(+), 10 deletions(-) create mode 100644 lib/CurlResponse.php create mode 100644 lib/Exception/ResourceRateLimitException.php diff --git a/lib/CurlRequest.php b/lib/CurlRequest.php index eb59477..f8b514b 100644 --- a/lib/CurlRequest.php +++ b/lib/CurlRequest.php @@ -9,6 +9,7 @@ use PHPShopify\Exception\CurlException; +use PHPShopify\Exception\ResourceRateLimitException; /* |-------------------------------------------------------------------------- @@ -47,6 +48,8 @@ protected static function init($url, $httpHeaders = array()) //Return the transfer as a string curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_HEADER, true); + $headers = array(); foreach ($httpHeaders as $key => $value) { $headers[] = "$key: $value"; @@ -141,15 +144,24 @@ public static function delete($url, $httpHeaders = array()) protected static function processRequest($ch) { # Check for 429 leaky bucket error - while(1) { - $output = curl_exec($ch); - self::$lastHttpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); - if(self::$lastHttpCode != 429) { - break; - } - usleep(500000); + while (1) { + $output = curl_exec($ch); + $response = new CurlResponse($output); + + self::$lastHttpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + if (self::$lastHttpCode != 429) { + break; + } + + $limitHeader = explode('/', $response->getHeader('X-Shopify-Shop-Api-Call-Limit'), 2); + + if (isset($limitHeader[1]) && $limitHeader[0] < $limitHeader[1]) { + throw new ResourceRateLimitException($response->getBody()); + } + + usleep(500000); } - + if (curl_errno($ch)) { throw new Exception\CurlException(curl_errno($ch) . ' : ' . curl_error($ch)); } @@ -157,7 +169,7 @@ protected static function processRequest($ch) // close curl resource to free up system resources curl_close($ch); - return $output; + return $response->getBody(); } -} \ No newline at end of file +} diff --git a/lib/CurlResponse.php b/lib/CurlResponse.php new file mode 100644 index 0000000..cc05405 --- /dev/null +++ b/lib/CurlResponse.php @@ -0,0 +1,73 @@ +parse($response); + } + + /** + * @param string $response + */ + private function parse($response) + { + $response = \explode("\r\n\r\n", $response); + if (\count($response) > 1) { + // We want the last two parts + $response = \array_slice($response, -2, 2); + list($headers, $body) = $response; + foreach (\explode("\r\n", $headers) as $header) { + $pair = \explode(': ', $header, 2); + if (isset($pair[1])) { + $this->headers[$pair[0]] = $pair[1]; + } + } + } else { + $body = $response[0]; + } + + $this->body = $body; + } + + /** + * @return array + */ + public function getHeaders() + { + return $this->headers; + } + + /** + * @param string $key + * + * @return string + */ + public function getHeader($key) + { + return isset($this->headers[$key]) ? $this->headers[$key] : null; + } + + /** + * @return string + */ + public function getBody() + { + return $this->body; + } + + public function __toString() + { + $body = $this->getBody(); + $body = $body ? : ''; + + return $body; + } +} diff --git a/lib/Exception/ResourceRateLimitException.php b/lib/Exception/ResourceRateLimitException.php new file mode 100644 index 0000000..1e7843d --- /dev/null +++ b/lib/Exception/ResourceRateLimitException.php @@ -0,0 +1,8 @@ +