From ab57ad4876b486071973b1bf1ac7501963599b8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Munsch?= Date: Mon, 1 Aug 2022 17:37:46 +0200 Subject: [PATCH] Fix Transport not signining request query parameters --- src/Transport/ApiInterface.php | 14 +++++-- src/Transport/Request.php | 67 +++++++++++++++++++++++++++------- 2 files changed, 63 insertions(+), 18 deletions(-) diff --git a/src/Transport/ApiInterface.php b/src/Transport/ApiInterface.php index 62bbfc7..6573988 100644 --- a/src/Transport/ApiInterface.php +++ b/src/Transport/ApiInterface.php @@ -115,9 +115,12 @@ class ApiInterface $this->setHeaders($request); $this->setTimestamp($request); $request->setEndpoint(self::$endpoint); - $request->addData([ - 'signature' => $this->calulateSignature($request) - ]); + $apiInterFace = $this; + // * Make request before adding signature + $request->makeRequest(); + $request->addSignatureCalculator(function ($request) use ($apiInterFace) { + return $apiInterFace->calulateSignature($request); + }); /** @var \Psr\Http\Message\ResponseInterface $response */ $response = $request->call(); @@ -178,7 +181,7 @@ class ApiInterface /** * Calculates request signature * - * @param Request $request + * @param \LDC\DAM\Client\Transport\Request $request * @return string * @throws \LDC\DAM\Client\Exceptions\DamException In case of failure. */ @@ -187,6 +190,9 @@ class ApiInterface $uri = \parse_url(sprintf('%s/%s', self::$endpoint, $request->uri)); $method = \strtolower($request->method->value); $parameters = $request->data; + if (count($query = Request::splitQuery($request->uri))) { + $parameters = \array_merge($parameters, $query); + } $signature = [ 'uri' => sprintf( diff --git a/src/Transport/Request.php b/src/Transport/Request.php index b3fa1e5..904b40a 100644 --- a/src/Transport/Request.php +++ b/src/Transport/Request.php @@ -74,6 +74,13 @@ class Request */ private $endpoint; + /** + * The signature calculator callback + * + * @var callable|null $calculateSignature + */ + private $calculateSignature; + /** * Request * @@ -124,31 +131,31 @@ class Request * * @return void */ - private function makeRequest(): void + public function makeRequest(): void { $this->request = function () { $uri = $this->uri; - // * If query merge query and data, set data to empty. + // * If GET query merge query and data, set data to empty. if ($this->method->equals(HttpMethods::get())) { // * Merge query in url with Data - $q = \parse_url($uri, \PHP_URL_QUERY) ?? ''; - $q = \strpos($q, '&') !== false ? explode('&', $q) : []; - $query = []; - foreach ($q as $qParam) { - $qParam = explode('=', $qParam, 2); + $query = self::splitQuery($uri); + $query = array_merge($this->data, $query); - $query[$qParam[0]] = $qParam[1]; - } // * Remove query part. $uri = strtok($uri, '?'); // * Append build query - $uri = sprintf("%s?%s", $uri, http_build_query(array_merge($query, $this->data))); - + $this->uri = sprintf("%s?%s", $uri, \urldecode(\http_build_query($query))); + // * clear Data $this->data = []; } + if ($calculator = $this->calculateSignature) { + $this->addData([ + 'signature' => $calculator($this) + ]); + } $request = new Psr7Request( \strtoupper($this->method), - sprintf('%s/%s', $this->endpoint, $uri), + sprintf('%s/%s', $this->endpoint, $this->uri), $this->headers ); $request = Psr7Utils::modifyRequest($request, [ @@ -172,11 +179,13 @@ class Request /** * Make the Http request * - * @return ResponseInterface + * @return \Psr\Http\Message\ResponseInterface */ public function call(): ResponseInterface { - $this->makeRequest(); + if (!$this->request) { + $this->makeRequest(); + } /** @var \GuzzleHttp\Psr7\Request */ $request = ($this->request)(); return $this->client->send($request, [ @@ -207,4 +216,34 @@ class Request { $this->data = \array_merge($this->data, $data); } + + /** + * Add signature calculator + * + * @param callable|null $calculateSignature + * @return void + */ + public function addSignatureCalculator(callable $calculateSignature = null) + { + $this->calculateSignature = $calculateSignature; + } + + /** + * Split query string into pieces + * + * @param string $uri + * @return array + */ + public static function splitQuery(string $uri): array + { + $q = \strval(\parse_url($uri, \PHP_URL_QUERY) ?? ''); + $q = \strpos($q, '&') !== false ? explode('&', $q) : (strlen($q) ? [$q] : []); + $query = []; + foreach ($q as $qParam) { + $qParam = explode('=', $qParam, 2); + + $query[$qParam[0]] = $qParam[1]; + } + return $query; + } }