From 4c6dbc9242ed03a056ce3433318e7e1f06969fce Mon Sep 17 00:00:00 2001 From: Adam Malone Date: Wed, 7 Oct 2020 09:21:31 +1100 Subject: [PATCH] Fixes #87 and ensures that user agents are only added once per unique string. --- src/Connector/Client.php | 26 +++++++++++++------------- tests/Endpoints/ClientTest.php | 10 +++++++++- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/Connector/Client.php b/src/Connector/Client.php index 2fe86648..089f27bd 100644 --- a/src/Connector/Client.php +++ b/src/Connector/Client.php @@ -75,29 +75,29 @@ public function getVersion() */ public function modifyOptions($options = []): array { - // Add the user agent header here so it can't be removed by other libraries. - $this->addOption('headers', [ - 'User-Agent' => sprintf( - "%s/%s (https://github.com/typhonius/acquia-php-sdk-v2)", - 'acquia-php-sdk-v2', - $this->getVersion() - ) - ]); - // Combine options set globally e.g. headers with options set by individual API calls e.g. form_params. $options = $this->options + $options; // This library can be standalone or as a dependency. Dependent libraries may also set their own user agent // which will make $options['headers']['User-Agent'] an array. - // We need to reverse the array of User-Agent headers to order this library's header first in log files. + // We need to array_unique() the array of User-Agent headers as multiple calls may include multiple of the same header. + // We also use array_unshift() to place this library's user agent first to order to have it appear at the beginning of log files. // As Guzzle joins arrays with a comma, we must implode with a space here to pass Guzzle a string. - if (is_array($options['headers']['User-Agent'])) { - $options['headers']['User-Agent'] = implode(' ', array_reverse($options['headers']['User-Agent'])); + $userAgent = sprintf( + "%s/%s (https://github.com/typhonius/acquia-php-sdk-v2)", + 'acquia-php-sdk-v2', + $this->getVersion() + ); + if (isset($options['headers']['User-Agent']) && is_array($options['headers']['User-Agent'])) { + array_unshift($options['headers']['User-Agent'], $userAgent); + $options['headers']['User-Agent'] = implode(' ', array_unique($options['headers']['User-Agent'])); + } else { + $options['headers']['User-Agent'] = $userAgent; } $options['query'] = $this->query; if (!empty($options['query']['filter']) && is_array($options['query']['filter'])) { - // Default to an AND filter. + // Default to an OR filter to increase returned responses. $options['query']['filter'] = implode(',', $options['query']['filter']); } diff --git a/tests/Endpoints/ClientTest.php b/tests/Endpoints/ClientTest.php index 4b6db8de..151e5219 100644 --- a/tests/Endpoints/ClientTest.php +++ b/tests/Endpoints/ClientTest.php @@ -82,6 +82,10 @@ public function testModifyOptions() // Set a number of options and queries as a dependent library would. $client->addOption('headers', ['User-Agent' => 'AcquiaCli/4.20']); + // Add a user agent twice to ensure that we only see it once in the request. + $client->addOption('headers', ['User-Agent' => 'AcquiaCli/4.20']); + $client->addOption('headers', ['User-Agent' => 'ZCli/1.1.1']); + $client->addOption('headers', ['User-Agent' => 'AaahCli/0.1']); $client->addQuery('filter', 'name=@*2014*'); $client->addQuery('filter', 'type=@*true*'); $client->addQuery('limit', '1'); @@ -95,12 +99,16 @@ public function testModifyOptions() ]; // Modify the request to ensure that all of the above get merged correctly. + // Run modifyOptions twice to ensure that multiple uses of it do not change + // the end result. + // @see https://github.com/typhonius/acquia-php-sdk-v2/issues/87 + $client->modifyOptions($options); $actualOptions = $client->modifyOptions($options); $version = $client->getVersion(); $expectedOptions = [ 'headers' => [ - 'User-Agent' => sprintf('acquia-php-sdk-v2/%s (https://github.com/typhonius/acquia-php-sdk-v2) AcquiaCli/4.20', $version) + 'User-Agent' => sprintf('acquia-php-sdk-v2/%s (https://github.com/typhonius/acquia-php-sdk-v2) AcquiaCli/4.20 ZCli/1.1.1 AaahCli/0.1', $version) ], 'json' => [ 'source' => 'source',