From 506ffdd8186507c57d19be2d83557ba325f1805c Mon Sep 17 00:00:00 2001 From: Kevin Hellemun <17928966+OGKevin@users.noreply.github.com> Date: Sat, 16 Mar 2019 19:36:13 +0100 Subject: [PATCH] Added response handler to retry 429. #109 --- src/Http/ApiClient.php | 32 ++++++++++++- src/Http/Handler/ResponseHandlerRateLimit.php | 48 +++++++++++++++++++ src/Http/RequestRetryer.php | 19 ++++++++ tests/Http/RequestRertyerForTest.php | 25 ++++++++++ tests/Http/ResponseHandlerRateLimitTest.php | 33 +++++++++++++ 5 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 src/Http/Handler/ResponseHandlerRateLimit.php create mode 100644 src/Http/RequestRetryer.php create mode 100644 tests/Http/RequestRertyerForTest.php create mode 100644 tests/Http/ResponseHandlerRateLimitTest.php diff --git a/src/Http/ApiClient.php b/src/Http/ApiClient.php index f72dcf0c..9f3be107 100644 --- a/src/Http/ApiClient.php +++ b/src/Http/ApiClient.php @@ -9,17 +9,19 @@ use bunq\Http\Handler\RequestHandlerEncryption; use bunq\Http\Handler\RequestHandlerSignature; use bunq\Http\Handler\ResponseHandlerError; +use bunq\Http\Handler\ResponseHandlerRateLimit; use bunq\Http\Handler\ResponseHandlerSignature; use bunq\Util\BunqEnumApiEnvironmentType; use GuzzleHttp\Client; use GuzzleHttp\Exception\RequestException; use GuzzleHttp\HandlerStack; use GuzzleHttp\Psr7\Uri; +use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; /** */ -class ApiClient +class ApiClient implements RequestRetryer { /** * Error constants. @@ -235,6 +237,33 @@ private function request( return $this->createBunqResponseRaw($response); } + /** + * @param RequestInterface $request + * @return ResponseInterface + */ + public function retryRequest(RequestInterface $request): ResponseInterface { + $this->initialize($request->getUri()); + + if ($request->getBody()->isSeekable()) { + $request->getBody()->rewind(); + } + + $body = $request->getBody()->getContents(); + + if (!$this->isBinary || !empty($body)) { + $body = json_decode($body, true); + } + + return $this->httpClient->request( + $request->getMethod(), + $request->getUri(), + $this->determineRequestOptions( + $body, + $request->getHeaders() + ) + ); + } + /** */ private function initialize(string $uri) @@ -298,6 +327,7 @@ private function determineMiddleware(): HandlerStack } $handlerStack->push(HandlerUtil::applyResponseHandler(new ResponseHandlerError())); + $handlerStack->push(HandlerUtil::applyResponseHandler(new ResponseHandlerRateLimit($this))); return $handlerStack; } diff --git a/src/Http/Handler/ResponseHandlerRateLimit.php b/src/Http/Handler/ResponseHandlerRateLimit.php new file mode 100644 index 00000000..2c31ab10 --- /dev/null +++ b/src/Http/Handler/ResponseHandlerRateLimit.php @@ -0,0 +1,48 @@ +retryer = $retryer; + } + + /** + * @param ResponseInterface $response + * @param RequestInterface $request + * + * @return ResponseInterface + */ + public function execute(ResponseInterface $response, RequestInterface $request): ResponseInterface + { + if ($response->getStatusCode() === 429) { + usleep(1500); + return $this->retryer->retryRequest($request); + } + + return $response; + } +} \ No newline at end of file diff --git a/src/Http/RequestRetryer.php b/src/Http/RequestRetryer.php new file mode 100644 index 00000000..2af91adb --- /dev/null +++ b/src/Http/RequestRetryer.php @@ -0,0 +1,19 @@ +execute(new Response(429), new Request('GET', 'https://whatthecommit.com/index.txt')); + + static::assertEquals(200, $response->getStatusCode()); + } + + /** + */ + public function testActualRequest() + { + static::markTestSkipped('how do we want to test this'); + } +}