From 75160b12821f7f4299cce7f0b69c83c1502ae071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anton=20Luka=20=C5=A0ijanec?= Date: Mon, 27 May 2024 13:08:29 +0200 Subject: 2024-02-19 upstream --- vendor/maxmind/web-service-common/CHANGELOG.md | 20 +++ vendor/maxmind/web-service-common/README.md | 2 +- vendor/maxmind/web-service-common/composer.json | 9 +- .../maxmind/web-service-common/dev-bin/release.sh | 116 +++++++------ vendor/maxmind/web-service-common/phpstan.neon | 7 + .../src/Exception/AuthenticationException.php | 2 + .../src/Exception/HttpException.php | 14 +- .../src/Exception/InsufficientFundsException.php | 2 + .../src/Exception/InvalidInputException.php | 2 + .../src/Exception/InvalidRequestException.php | 16 +- .../src/Exception/IpAddressNotFoundException.php | 2 + .../src/Exception/PermissionRequiredException.php | 2 + .../src/Exception/WebServiceException.php | 2 + .../web-service-common/src/WebService/Client.php | 180 ++++++++++++++------- .../src/WebService/Http/CurlRequest.php | 76 ++++----- .../src/WebService/Http/Request.php | 20 +-- .../src/WebService/Http/RequestFactory.php | 15 +- 17 files changed, 289 insertions(+), 198 deletions(-) create mode 100644 vendor/maxmind/web-service-common/phpstan.neon (limited to 'vendor/maxmind/web-service-common') diff --git a/vendor/maxmind/web-service-common/CHANGELOG.md b/vendor/maxmind/web-service-common/CHANGELOG.md index 6aaa749..1f1b9a5 100644 --- a/vendor/maxmind/web-service-common/CHANGELOG.md +++ b/vendor/maxmind/web-service-common/CHANGELOG.md @@ -1,6 +1,26 @@ CHANGELOG ========= +0.9.0 (2022-03-28) +------------------ + +* Improved internal type hint usage. + +0.8.1 (2020-11-02) +------------------ + +* We now correctly handle responses without a `Content-Type` header. In 0.8.0, + such responses could lead to a type error. In particular, this affected the + minFraud Report Transaction endpoint, which returns a response with no + content. Reported by Dmitry Malashko. GitHub #99 on + `maxmind/minfraud-api-php`. + +0.8.0 (2020-10-01) +------------------ + +* PHP 7.2 or greater is now required. +* Added additional type hints. + 0.7.0 (2020-05-06) ------------------ diff --git a/vendor/maxmind/web-service-common/README.md b/vendor/maxmind/web-service-common/README.md index e3c64d3..c253a89 100644 --- a/vendor/maxmind/web-service-common/README.md +++ b/vendor/maxmind/web-service-common/README.md @@ -5,7 +5,7 @@ shared code between MaxMind's various web service client APIs. ## Requirements ## -The library requires PHP 5.6 or greater. +The library requires PHP 7.2 or greater. There are several other dependencies as defined in the `composer.json` file. diff --git a/vendor/maxmind/web-service-common/composer.json b/vendor/maxmind/web-service-common/composer.json index 6d1bbe4..14800df 100644 --- a/vendor/maxmind/web-service-common/composer.json +++ b/vendor/maxmind/web-service-common/composer.json @@ -12,15 +12,16 @@ } ], "require": { - "php": ">=5.6", + "php": ">=7.2", "composer/ca-bundle": "^1.0.3", "ext-curl": "*", "ext-json": "*" }, "require-dev": { - "friendsofphp/php-cs-fixer": "2.*", - "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0", - "squizlabs/php_codesniffer": "3.*" + "friendsofphp/php-cs-fixer": "3.*", + "phpunit/phpunit": "^8.0 || ^9.0", + "squizlabs/php_codesniffer": "3.*", + "phpstan/phpstan": "*" }, "autoload": { "psr-4": { diff --git a/vendor/maxmind/web-service-common/dev-bin/release.sh b/vendor/maxmind/web-service-common/dev-bin/release.sh index a5de030..0eee51c 100644 --- a/vendor/maxmind/web-service-common/dev-bin/release.sh +++ b/vendor/maxmind/web-service-common/dev-bin/release.sh @@ -1,60 +1,56 @@ -#!/bin/bash - -set -eu -o pipefail - - -changelog=$(cat CHANGELOG.md) - -regex=' -([0-9]+\.[0-9]+\.[0-9]+) \(([0-9]{4}-[0-9]{2}-[0-9]{2})\) --* - -((.| -)*) -' - -if [[ ! $changelog =~ $regex ]]; then - echo "Could not find date line in change log!" - exit 1 -fi - -version="${BASH_REMATCH[1]}" -date="${BASH_REMATCH[2]}" -notes="$(echo "${BASH_REMATCH[3]}" | sed -n -E '/^[0-9]+\.[0-9]+\.[0-9]+/,$!p')" - -if [[ "$date" != $(date +"%Y-%m-%d") ]]; then - echo "$date is not today!" - exit 1 -fi - -tag="v$version" - -if [ -n "$(git status --porcelain)" ]; then - echo ". is not clean." >&2 - exit 1 -fi - -php composer.phar self-update -php composer.phar update - -./vendor/bin/phpunit - -echo "Release notes for $tag:" -echo "$notes" - -read -e -p "Commit changes and push to origin? " should_push - -if [ "$should_push" != "y" ]; then - echo "Aborting" - exit 1 -fi - -git push - -message="$version - -$notes" - -hub release create -m "$message" "$tag" - -git push --tags +#!/bin/bash + +set -eu -o pipefail + + +changelog=$(cat CHANGELOG.md) + +regex=' +([0-9]+\.[0-9]+\.[0-9]+) \(([0-9]{4}-[0-9]{2}-[0-9]{2})\) +-* + +((.| +)*) +' + +if [[ ! $changelog =~ $regex ]]; then + echo "Could not find date line in change log!" + exit 1 +fi + +version="${BASH_REMATCH[1]}" +date="${BASH_REMATCH[2]}" +notes="$(echo "${BASH_REMATCH[3]}" | sed -n -E '/^[0-9]+\.[0-9]+\.[0-9]+/,$!p')" + +if [[ "$date" != $(date +"%Y-%m-%d") ]]; then + echo "$date is not today!" + exit 1 +fi + +tag="v$version" + +if [ -n "$(git status --porcelain)" ]; then + echo ". is not clean." >&2 + exit 1 +fi + +php composer.phar self-update +php composer.phar update + +./vendor/bin/phpunit + +echo "Release notes for $tag:" +echo "$notes" + +read -e -p "Commit changes and push to origin? " should_push + +if [ "$should_push" != "y" ]; then + echo "Aborting" + exit 1 +fi + +git push + +gh release create --target "$(git branch --show-current)" -t "$version" -n "$notes" "$tag" + +git push --tags diff --git a/vendor/maxmind/web-service-common/phpstan.neon b/vendor/maxmind/web-service-common/phpstan.neon new file mode 100644 index 0000000..2d35ad9 --- /dev/null +++ b/vendor/maxmind/web-service-common/phpstan.neon @@ -0,0 +1,7 @@ +parameters: + level: 6 + paths: + - src + - tests + checkMissingIterableValueType: false + diff --git a/vendor/maxmind/web-service-common/src/Exception/AuthenticationException.php b/vendor/maxmind/web-service-common/src/Exception/AuthenticationException.php index 54258ca..5843a6d 100644 --- a/vendor/maxmind/web-service-common/src/Exception/AuthenticationException.php +++ b/vendor/maxmind/web-service-common/src/Exception/AuthenticationException.php @@ -1,5 +1,7 @@ uri = $uri; parent::__construct($message, $httpStatus, $previous); } - public function getUri() + public function getUri(): string { return $this->uri; } - public function getStatusCode() + public function getStatusCode(): int { return $this->getCode(); } diff --git a/vendor/maxmind/web-service-common/src/Exception/InsufficientFundsException.php b/vendor/maxmind/web-service-common/src/Exception/InsufficientFundsException.php index 4d6b3be..4639a3e 100644 --- a/vendor/maxmind/web-service-common/src/Exception/InsufficientFundsException.php +++ b/vendor/maxmind/web-service-common/src/Exception/InsufficientFundsException.php @@ -1,5 +1,7 @@ error = $error; parent::__construct($message, $httpStatus, $uri, $previous); } - public function getErrorCode() + public function getErrorCode(): string { return $this->error; } diff --git a/vendor/maxmind/web-service-common/src/Exception/IpAddressNotFoundException.php b/vendor/maxmind/web-service-common/src/Exception/IpAddressNotFoundException.php index 1a743a1..3bd2ce9 100644 --- a/vendor/maxmind/web-service-common/src/Exception/IpAddressNotFoundException.php +++ b/vendor/maxmind/web-service-common/src/Exception/IpAddressNotFoundException.php @@ -1,5 +1,7 @@ accountId = $accountId; $this->licenseKey = $licenseKey; @@ -61,6 +104,9 @@ class Client if (isset($options['host'])) { $this->host = $options['host']; } + if (isset($options['useHttps'])) { + $this->useHttps = $options['useHttps']; + } if (isset($options['userAgent'])) { $this->userAgentPrefix = $options['userAgent'] . ' '; } @@ -96,9 +142,9 @@ class Client * @throws WebServiceException when some other error occurs. This also * serves as the base class for the above exceptions. * - * @return array The decoded content of a successful response + * @return array|null The decoded content of a successful response */ - public function post($service, $path, $input) + public function post(string $service, string $path, array $input): ?array { $requestBody = json_encode($input); if ($requestBody === false) { @@ -113,7 +159,7 @@ class Client ['Content-Type: application/json'] ); - list($statusCode, $contentType, $responseBody) = $request->post($requestBody); + [$statusCode, $contentType, $responseBody] = $request->post($requestBody); return $this->handleResponse( $statusCode, @@ -124,11 +170,13 @@ class Client ); } - public function get($service, $path) + public function get(string $service, string $path): ?array { - $request = $this->createRequest($path); + $request = $this->createRequest( + $path + ); - list($statusCode, $contentType, $responseBody) = $request->get(); + [$statusCode, $contentType, $responseBody] = $request->get(); return $this->handleResponse( $statusCode, @@ -139,15 +187,15 @@ class Client ); } - private function userAgent() + private function userAgent(): string { $curlVersion = curl_version(); - return $this->userAgentPrefix . 'MaxMind-WS-API/' . self::VERSION . ' PHP/' . PHP_VERSION . + return $this->userAgentPrefix . 'MaxMind-WS-API/' . self::VERSION . ' PHP/' . \PHP_VERSION . ' curl/' . $curlVersion['version']; } - private function createRequest($path, $headers = []) + private function createRequest(string $path, array $headers = []): Http\Request { array_push( $headers, @@ -170,11 +218,11 @@ class Client } /** - * @param int $statusCode the HTTP status code of the response - * @param string $contentType the Content-Type of the response - * @param string $responseBody the response body - * @param string $service the name of the service - * @param string $path the path used in the request + * @param int $statusCode the HTTP status code of the response + * @param string|null $contentType the Content-Type of the response + * @param string|null $responseBody the response body + * @param string $service the name of the service + * @param string $path the path used in the request * * @throws AuthenticationException when there is an issue authenticating the * request @@ -185,15 +233,15 @@ class Client * @throws WebServiceException when some other error occurs. This also * serves as the base class for the above exceptions * - * @return array The decoded content of a successful response + * @return array|null The decoded content of a successful response */ private function handleResponse( - $statusCode, - $contentType, - $responseBody, - $service, - $path - ) { + int $statusCode, + ?string $contentType, + ?string $responseBody, + string $service, + string $path + ): ?array { if ($statusCode >= 400 && $statusCode <= 499) { $this->handle4xx($statusCode, $contentType, $responseBody, $service, $path); } elseif ($statusCode >= 500) { @@ -208,20 +256,26 @@ class Client /** * @return string describing the JSON error */ - private function jsonErrorDescription() + private function jsonErrorDescription(): string { $errno = json_last_error(); + switch ($errno) { - case JSON_ERROR_DEPTH: + case \JSON_ERROR_DEPTH: return 'The maximum stack depth has been exceeded.'; - case JSON_ERROR_STATE_MISMATCH: + + case \JSON_ERROR_STATE_MISMATCH: return 'Invalid or malformed JSON.'; - case JSON_ERROR_CTRL_CHAR: + + case \JSON_ERROR_CTRL_CHAR: return 'Control character error.'; - case JSON_ERROR_SYNTAX: + + case \JSON_ERROR_SYNTAX: return 'Syntax error.'; - case JSON_ERROR_UTF8: + + case \JSON_ERROR_UTF8: return 'Malformed UTF-8 characters.'; + default: return "Other JSON error ($errno)."; } @@ -232,17 +286,17 @@ class Client * * @return string the constructed URL */ - private function urlFor($path) + private function urlFor(string $path): string { - return 'https://' . $this->host . $path; + return ($this->useHttps ? 'https://' : 'http://') . $this->host . $path; } /** - * @param int $statusCode the HTTP status code - * @param string $contentType the response content-type - * @param string $body the response body - * @param string $service the service name - * @param string $path the path used in the request + * @param int $statusCode the HTTP status code + * @param string|null $contentType the response content-type + * @param string|null $body the response body + * @param string $service the service name + * @param string $path the path used in the request * * @throws AuthenticationException * @throws HttpException @@ -250,20 +304,20 @@ class Client * @throws InvalidRequestException */ private function handle4xx( - $statusCode, - $contentType, - $body, - $service, - $path - ) { - if (\strlen($body) === 0) { + int $statusCode, + ?string $contentType, + ?string $body, + string $service, + string $path + ): void { + if ($body === null || $body === '') { throw new HttpException( "Received a $statusCode error for $service with no body", $statusCode, $this->urlFor($path) ); } - if (!strstr($contentType, 'json')) { + if ($contentType === null || !strstr($contentType, 'json')) { throw new HttpException( "Received a $statusCode error for $service with " . 'the following body: ' . $body, @@ -311,11 +365,11 @@ class Client * @throws InsufficientFundsException */ private function handleWebServiceError( - $message, - $code, - $statusCode, - $path - ) { + string $message, + string $code, + int $statusCode, + string $path + ): void { switch ($code) { case 'IP_ADDRESS_NOT_FOUND': case 'IP_ADDRESS_RESERVED': @@ -325,6 +379,7 @@ class Client $statusCode, $this->urlFor($path) ); + case 'ACCOUNT_ID_REQUIRED': case 'ACCOUNT_ID_UNKNOWN': case 'AUTHORIZATION_INVALID': @@ -337,6 +392,7 @@ class Client $statusCode, $this->urlFor($path) ); + case 'OUT_OF_QUERIES': case 'INSUFFICIENT_FUNDS': throw new InsufficientFundsException( @@ -345,6 +401,7 @@ class Client $statusCode, $this->urlFor($path) ); + case 'PERMISSION_REQUIRED': throw new PermissionRequiredException( $message, @@ -352,6 +409,7 @@ class Client $statusCode, $this->urlFor($path) ); + default: throw new InvalidRequestException( $message, @@ -369,7 +427,7 @@ class Client * * @throws HttpException */ - private function handle5xx($statusCode, $service, $path) + private function handle5xx(int $statusCode, string $service, string $path): void { throw new HttpException( "Received a server error ($statusCode) for $service", @@ -385,7 +443,7 @@ class Client * * @throws HttpException */ - private function handleUnexpectedStatus($statusCode, $service, $path) + private function handleUnexpectedStatus(int $statusCode, string $service, string $path): void { throw new HttpException( 'Received an unexpected HTTP status ' . @@ -396,22 +454,22 @@ class Client } /** - * @param int $statusCode the HTTP status code - * @param string $body the successful request body - * @param string $service the service name + * @param int $statusCode the HTTP status code + * @param string|null $body the successful request body + * @param string $service the service name * * @throws WebServiceException if a response body is included but not * expected, or is not expected but not * included, or is expected and included * but cannot be decoded as JSON * - * @return array the decoded request body + * @return array|null the decoded request body */ - private function handleSuccess($statusCode, $body, $service) + private function handleSuccess(int $statusCode, ?string $body, string $service): ?array { // A 204 should have no response body if ($statusCode === 204) { - if (\strlen($body) !== 0) { + if ($body !== null && $body !== '') { throw new WebServiceException( "Received a 204 response for $service along with an " . "unexpected HTTP body: $body" @@ -422,7 +480,7 @@ class Client } // A 200 should have a valid JSON body - if (\strlen($body) === 0) { + if ($body === null || $body === '') { throw new WebServiceException( "Received a 200 response for $service but did not " . 'receive a HTTP body.' @@ -441,7 +499,7 @@ class Client return $decodedContent; } - private function getCaBundle() + private function getCaBundle(): ?string { $curlVersion = curl_version(); diff --git a/vendor/maxmind/web-service-common/src/WebService/Http/CurlRequest.php b/vendor/maxmind/web-service-common/src/WebService/Http/CurlRequest.php index 501b2af..4b9a70b 100644 --- a/vendor/maxmind/web-service-common/src/WebService/Http/CurlRequest.php +++ b/vendor/maxmind/web-service-common/src/WebService/Http/CurlRequest.php @@ -1,5 +1,7 @@ url = $url; $this->options = $options; @@ -38,69 +36,65 @@ class CurlRequest implements Request } /** - * @param string $body - * * @throws HttpException - * - * @return array */ - public function post($body) + public function post(string $body): array { $curl = $this->createCurl(); - curl_setopt($curl, CURLOPT_POST, true); - curl_setopt($curl, CURLOPT_POSTFIELDS, $body); + curl_setopt($curl, \CURLOPT_POST, true); + curl_setopt($curl, \CURLOPT_POSTFIELDS, $body); return $this->execute($curl); } - public function get() + public function get(): array { $curl = $this->createCurl(); - curl_setopt($curl, CURLOPT_HTTPGET, true); + curl_setopt($curl, \CURLOPT_HTTPGET, true); return $this->execute($curl); } /** - * @return resource + * @return \CurlHandle */ private function createCurl() { curl_reset($this->ch); $opts = []; - $opts[CURLOPT_URL] = $this->url; + $opts[\CURLOPT_URL] = $this->url; if (!empty($this->options['caBundle'])) { - $opts[CURLOPT_CAINFO] = $this->options['caBundle']; + $opts[\CURLOPT_CAINFO] = $this->options['caBundle']; } - $opts[CURLOPT_ENCODING] = ''; - $opts[CURLOPT_SSL_VERIFYHOST] = 2; - $opts[CURLOPT_FOLLOWLOCATION] = false; - $opts[CURLOPT_SSL_VERIFYPEER] = true; - $opts[CURLOPT_RETURNTRANSFER] = true; + $opts[\CURLOPT_ENCODING] = ''; + $opts[\CURLOPT_SSL_VERIFYHOST] = 2; + $opts[\CURLOPT_FOLLOWLOCATION] = false; + $opts[\CURLOPT_SSL_VERIFYPEER] = true; + $opts[\CURLOPT_RETURNTRANSFER] = true; - $opts[CURLOPT_HTTPHEADER] = $this->options['headers']; - $opts[CURLOPT_USERAGENT] = $this->options['userAgent']; - $opts[CURLOPT_PROXY] = $this->options['proxy']; + $opts[\CURLOPT_HTTPHEADER] = $this->options['headers']; + $opts[\CURLOPT_USERAGENT] = $this->options['userAgent']; + $opts[\CURLOPT_PROXY] = $this->options['proxy']; // The defined()s are here as the *_MS opts are not available on older // cURL versions $connectTimeout = $this->options['connectTimeout']; if (\defined('CURLOPT_CONNECTTIMEOUT_MS')) { - $opts[CURLOPT_CONNECTTIMEOUT_MS] = ceil($connectTimeout * 1000); + $opts[\CURLOPT_CONNECTTIMEOUT_MS] = ceil($connectTimeout * 1000); } else { - $opts[CURLOPT_CONNECTTIMEOUT] = ceil($connectTimeout); + $opts[\CURLOPT_CONNECTTIMEOUT] = ceil($connectTimeout); } $timeout = $this->options['timeout']; if (\defined('CURLOPT_TIMEOUT_MS')) { - $opts[CURLOPT_TIMEOUT_MS] = ceil($timeout * 1000); + $opts[\CURLOPT_TIMEOUT_MS] = ceil($timeout * 1000); } else { - $opts[CURLOPT_TIMEOUT] = ceil($timeout); + $opts[\CURLOPT_TIMEOUT] = ceil($timeout); } curl_setopt_array($this->ch, $opts); @@ -109,13 +103,11 @@ class CurlRequest implements Request } /** - * @param resource $curl + * @param \CurlHandle $curl * * @throws HttpException - * - * @return array */ - private function execute($curl) + private function execute($curl): array { $body = curl_exec($curl); if ($errno = curl_errno($curl)) { @@ -128,9 +120,17 @@ class CurlRequest implements Request ); } - $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); - $contentType = curl_getinfo($curl, CURLINFO_CONTENT_TYPE); - - return [$statusCode, $contentType, $body]; + $statusCode = curl_getinfo($curl, \CURLINFO_HTTP_CODE); + $contentType = curl_getinfo($curl, \CURLINFO_CONTENT_TYPE); + + return [ + $statusCode, + // The PHP docs say "Content-Type: of the requested document. NULL + // indicates server did not send valid Content-Type: header" for + // CURLINFO_CONTENT_TYPE. However, it will return FALSE if no header + // is set. To keep our types simple, we return null in this case. + ($contentType === false ? null : $contentType), + $body, + ]; } } diff --git a/vendor/maxmind/web-service-common/src/WebService/Http/Request.php b/vendor/maxmind/web-service-common/src/WebService/Http/Request.php index 283e05c..6f5a5ab 100644 --- a/vendor/maxmind/web-service-common/src/WebService/Http/Request.php +++ b/vendor/maxmind/web-service-common/src/WebService/Http/Request.php @@ -1,5 +1,7 @@ ch)) { @@ -34,13 +39,7 @@ class RequestFactory return $this->ch; } - /** - * @param string $url - * @param array $options - * - * @return Request - */ - public function request($url, $options) + public function request(string $url, array $options): Request { $options['curlHandle'] = $this->getCurlHandle(); -- cgit v1.2.3