MDL-86462 lib: Upgrade guzzle and friends
- guzzlehttp/guzzle to version 7.10.0 - guzzlehttp/psr7 to version 2.8.0 - guzzlehttp/promises to version 2.3.0 - kevinrob/guzzle-cache-middleware to version 7.0.0 The updates add support for PHP 8.5. Signed-off-by: Daniel Ziegenberg <[email protected]>
This commit is contained in:
@@ -2,6 +2,25 @@
|
||||
|
||||
Please refer to [UPGRADING](UPGRADING.md) guide for upgrading to a major version.
|
||||
|
||||
## 7.10.0 - 2025-08-23
|
||||
|
||||
### Added
|
||||
|
||||
- Support for PHP 8.5
|
||||
|
||||
### Changed
|
||||
|
||||
- Adjusted `guzzlehttp/promises` version constraint to `^2.3`
|
||||
- Adjusted `guzzlehttp/psr7` version constraint to `^2.8`
|
||||
|
||||
|
||||
## 7.9.3 - 2025-03-27
|
||||
|
||||
### Changed
|
||||
|
||||
- Remove explicit content-length header for GET requests
|
||||
- Improve compatibility with bad servers for boolean cookie values
|
||||
|
||||
|
||||
## 7.9.2 - 2024-07-24
|
||||
|
||||
|
||||
@@ -81,8 +81,8 @@
|
||||
"require": {
|
||||
"php": "^7.2.5 || ^8.0",
|
||||
"ext-json": "*",
|
||||
"guzzlehttp/promises": "^1.5.3 || ^2.0.3",
|
||||
"guzzlehttp/psr7": "^2.7.0",
|
||||
"guzzlehttp/promises": "^2.3",
|
||||
"guzzlehttp/psr7": "^2.8",
|
||||
"psr/http-client": "^1.0",
|
||||
"symfony/deprecation-contracts": "^2.2 || ^3.0"
|
||||
},
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "guzzle",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
See instructions in lib/guzzlehttp/readme_moodle.md
|
||||
See instructions in public/lib/guzzlehttp/readme_moodle.md
|
||||
|
||||
@@ -62,6 +62,10 @@ class SetCookie
|
||||
if (is_numeric($value)) {
|
||||
$data[$search] = (int) $value;
|
||||
}
|
||||
} elseif ($search === 'Secure' || $search === 'Discard' || $search === 'HttpOnly') {
|
||||
if ($value) {
|
||||
$data[$search] = true;
|
||||
}
|
||||
} else {
|
||||
$data[$search] = $value;
|
||||
}
|
||||
|
||||
@@ -125,7 +125,9 @@ class CurlFactory implements CurlFactoryInterface
|
||||
unset($easy->handle);
|
||||
|
||||
if (\count($this->handles) >= $this->maxHandles) {
|
||||
\curl_close($resource);
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
\curl_close($resource);
|
||||
}
|
||||
} else {
|
||||
// Remove all callback functions as they can hold onto references
|
||||
// and are not cleaned up by curl_reset. Using curl_setopt_array
|
||||
@@ -729,7 +731,10 @@ class CurlFactory implements CurlFactoryInterface
|
||||
public function __destruct()
|
||||
{
|
||||
foreach ($this->handles as $id => $handle) {
|
||||
\curl_close($handle);
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
\curl_close($handle);
|
||||
}
|
||||
|
||||
unset($this->handles[$id]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,7 +240,10 @@ class CurlMultiHandler
|
||||
$handle = $this->handles[$id]['easy']->handle;
|
||||
unset($this->delays[$id], $this->handles[$id]);
|
||||
\curl_multi_remove_handle($this->_mh, $handle);
|
||||
\curl_close($handle);
|
||||
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
\curl_close($handle);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -17,10 +17,10 @@ class Proxy
|
||||
* Sends synchronous requests to a specific handler while sending all other
|
||||
* requests to another handler.
|
||||
*
|
||||
* @param callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface $default Handler used for normal responses
|
||||
* @param callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface $sync Handler used for synchronous responses.
|
||||
* @param callable(RequestInterface, array): PromiseInterface $default Handler used for normal responses
|
||||
* @param callable(RequestInterface, array): PromiseInterface $sync Handler used for synchronous responses.
|
||||
*
|
||||
* @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the composed handler.
|
||||
* @return callable(RequestInterface, array): PromiseInterface Returns the composed handler.
|
||||
*/
|
||||
public static function wrapSync(callable $default, callable $sync): callable
|
||||
{
|
||||
@@ -37,10 +37,10 @@ class Proxy
|
||||
* performance benefits of curl while still supporting true streaming
|
||||
* through the StreamHandler.
|
||||
*
|
||||
* @param callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface $default Handler used for non-streaming responses
|
||||
* @param callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface $streaming Handler used for streaming responses
|
||||
* @param callable(RequestInterface, array): PromiseInterface $default Handler used for non-streaming responses
|
||||
* @param callable(RequestInterface, array): PromiseInterface $streaming Handler used for streaming responses
|
||||
*
|
||||
* @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the composed handler.
|
||||
* @return callable(RequestInterface, array): PromiseInterface Returns the composed handler.
|
||||
*/
|
||||
public static function wrapStreaming(callable $default, callable $streaming): callable
|
||||
{
|
||||
|
||||
@@ -53,8 +53,14 @@ class StreamHandler
|
||||
$request = $request->withoutHeader('Expect');
|
||||
|
||||
// Append a content-length header if body size is zero to match
|
||||
// cURL's behavior.
|
||||
if (0 === $request->getBody()->getSize()) {
|
||||
// the behavior of `CurlHandler`
|
||||
if (
|
||||
(
|
||||
0 === \strcasecmp('PUT', $request->getMethod())
|
||||
|| 0 === \strcasecmp('POST', $request->getMethod())
|
||||
)
|
||||
&& 0 === $request->getBody()->getSize()
|
||||
) {
|
||||
$request = $request->withHeader('Content-Length', '0');
|
||||
}
|
||||
|
||||
@@ -327,8 +333,15 @@ class StreamHandler
|
||||
);
|
||||
|
||||
return $this->createResource(
|
||||
function () use ($uri, &$http_response_header, $contextResource, $context, $options, $request) {
|
||||
function () use ($uri, $contextResource, $context, $options, $request) {
|
||||
$resource = @\fopen((string) $uri, 'r', false, $contextResource);
|
||||
|
||||
// See https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_the_http_response_header_predefined_variable
|
||||
if (function_exists('http_get_last_response_headers')) {
|
||||
/** @var array|null */
|
||||
$http_response_header = \http_get_last_response_headers();
|
||||
}
|
||||
|
||||
$this->lastHeaders = $http_response_header ?? [];
|
||||
|
||||
if (false === $resource) {
|
||||
|
||||
@@ -187,12 +187,12 @@ final class Middleware
|
||||
* Middleware that logs requests, responses, and errors using a message
|
||||
* formatter.
|
||||
*
|
||||
* @phpstan-param \Psr\Log\LogLevel::* $logLevel Level at which to log requests.
|
||||
*
|
||||
* @param LoggerInterface $logger Logs messages.
|
||||
* @param MessageFormatterInterface|MessageFormatter $formatter Formatter used to create message strings.
|
||||
* @param string $logLevel Level at which to log requests.
|
||||
*
|
||||
* @phpstan-param \Psr\Log\LogLevel::* $logLevel Level at which to log requests.
|
||||
*
|
||||
* @return callable Returns a function that accepts the next handler.
|
||||
*/
|
||||
public static function log(LoggerInterface $logger, $formatter, string $logLevel = 'info'): callable
|
||||
|
||||
@@ -86,7 +86,7 @@ class Pool implements PromisorInterface
|
||||
* @param ClientInterface $client Client used to send the requests
|
||||
* @param array|\Iterator $requests Requests to send concurrently.
|
||||
* @param array $options Passes through the options available in
|
||||
* {@see \GuzzleHttp\Pool::__construct}
|
||||
* {@see Pool::__construct}
|
||||
*
|
||||
* @return array Returns an array containing the response or an exception
|
||||
* in the same order that the requests were sent.
|
||||
|
||||
@@ -79,7 +79,7 @@ final class Utils
|
||||
*
|
||||
* The returned handler is not wrapped by any default middlewares.
|
||||
*
|
||||
* @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the best handler for the given system.
|
||||
* @return callable(\Psr\Http\Message\RequestInterface, array): Promise\PromiseInterface Returns the best handler for the given system.
|
||||
*
|
||||
* @throws \RuntimeException if no viable Handler is available.
|
||||
*/
|
||||
|
||||
@@ -50,7 +50,7 @@ function debug_resource($value = null)
|
||||
*
|
||||
* The returned handler is not wrapped by any default middlewares.
|
||||
*
|
||||
* @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the best handler for the given system.
|
||||
* @return callable(\Psr\Http\Message\RequestInterface, array): Promise\PromiseInterface Returns the best handler for the given system.
|
||||
*
|
||||
* @throws \RuntimeException if no viable Handler is available.
|
||||
*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# guzzle-cache-middleware
|
||||
|
||||
[](https://packagist.org/packages/kevinrob/guzzle-cache-middleware) [](https://packagist.org/packages/kevinrob/guzzle-cache-middleware) [](https://packagist.org/packages/kevinrob/guzzle-cache-middleware)
|
||||
 [](https://scrutinizer-ci.com/g/Kevinrob/guzzle-cache-middleware/?branch=master) [](https://scrutinizer-ci.com/g/Kevinrob/guzzle-cache-middleware/?branch=master)
|
||||

|
||||
|
||||
|
||||
A HTTP Cache for [Guzzle](https://github.com/guzzle/guzzle) 6+. It's a simple Middleware to be added in the HandlerStack.
|
||||
@@ -12,10 +12,10 @@ A HTTP Cache for [Guzzle](https://github.com/guzzle/guzzle) 6+. It's a simple Mi
|
||||
- Assured compatibility with PSR-7
|
||||
|
||||
## Built-in storage interfaces
|
||||
- [Doctrine cache](https://github.com/doctrine/cache)
|
||||
- [Laravel cache](https://laravel.com/docs/5.2/cache)
|
||||
- [Flysystem](https://github.com/thephpleague/flysystem)
|
||||
- [PSR6](https://github.com/php-fig/cache)
|
||||
- [PSR16](https://github.com/php-fig/simple-cache)
|
||||
- [WordPress Object Cache](https://codex.wordpress.org/Class_Reference/WP_Object_Cache)
|
||||
|
||||
## Installation
|
||||
@@ -47,49 +47,6 @@ $client = new Client(['handler' => $stack]);
|
||||
|
||||
# Examples
|
||||
|
||||
## Doctrine/Cache
|
||||
You can use a cache from `Doctrine/Cache`:
|
||||
```php
|
||||
[...]
|
||||
use Doctrine\Common\Cache\FilesystemCache;
|
||||
use Kevinrob\GuzzleCache\Strategy\PrivateCacheStrategy;
|
||||
use Kevinrob\GuzzleCache\Storage\DoctrineCacheStorage;
|
||||
|
||||
[...]
|
||||
$stack->push(
|
||||
new CacheMiddleware(
|
||||
new PrivateCacheStrategy(
|
||||
new DoctrineCacheStorage(
|
||||
new FilesystemCache('/tmp/')
|
||||
)
|
||||
)
|
||||
),
|
||||
'cache'
|
||||
);
|
||||
```
|
||||
|
||||
You can use `ChainCache` for using multiple `CacheProvider` instances. With that provider, you have to sort the different caches from the faster to the slower. Like that, you can have a very fast cache.
|
||||
```php
|
||||
[...]
|
||||
use Doctrine\Common\Cache\ChainCache;
|
||||
use Doctrine\Common\Cache\ArrayCache;
|
||||
use Doctrine\Common\Cache\FilesystemCache;
|
||||
use Kevinrob\GuzzleCache\Strategy\PrivateCacheStrategy;
|
||||
use Kevinrob\GuzzleCache\Storage\DoctrineCacheStorage;
|
||||
|
||||
[...]
|
||||
$stack->push(new CacheMiddleware(
|
||||
new PrivateCacheStrategy(
|
||||
new DoctrineCacheStorage(
|
||||
new ChainCache([
|
||||
new ArrayCache(),
|
||||
new FilesystemCache('/tmp/'),
|
||||
])
|
||||
)
|
||||
)
|
||||
), 'cache');
|
||||
```
|
||||
|
||||
## Laravel cache
|
||||
You can use a cache with Laravel, e.g. Redis, Memcache etc.:
|
||||
```php
|
||||
@@ -115,7 +72,7 @@ $stack->push(
|
||||
## Flysystem
|
||||
```php
|
||||
[...]
|
||||
use League\Flysystem\Adapter\Local;
|
||||
use League\Flysystem\Local\LocalFilesystemAdapter;
|
||||
use Kevinrob\GuzzleCache\Strategy\PrivateCacheStrategy;
|
||||
use Kevinrob\GuzzleCache\Storage\FlysystemStorage;
|
||||
|
||||
@@ -125,7 +82,7 @@ $stack->push(
|
||||
new CacheMiddleware(
|
||||
new PrivateCacheStrategy(
|
||||
new FlysystemStorage(
|
||||
new Local('/path/to/cache')
|
||||
new LocalFilesystemAdapter('/path/to/cache')
|
||||
)
|
||||
)
|
||||
),
|
||||
@@ -155,19 +112,20 @@ $stack->push(
|
||||
It's possible to add a public shared cache to the stack:
|
||||
```php
|
||||
[...]
|
||||
use Doctrine\Common\Cache\FilesystemCache;
|
||||
use Doctrine\Common\Cache\PredisCache;
|
||||
use Cache\Adapter\PHPArray\ArrayCachePool;
|
||||
use Kevinrob\GuzzleCache\Strategy\PrivateCacheStrategy;
|
||||
use Kevinrob\GuzzleCache\Strategy\PublicCacheStrategy;
|
||||
use Kevinrob\GuzzleCache\Storage\DoctrineCacheStorage;
|
||||
use Kevinrob\GuzzleCache\Storage\Psr6CacheStorage;
|
||||
use League\Flysystem\Local\LocalFilesystemAdapter;
|
||||
use Kevinrob\GuzzleCache\Storage\FlysystemStorage;
|
||||
|
||||
[...]
|
||||
// Private caching
|
||||
$stack->push(
|
||||
new CacheMiddleware(
|
||||
new PrivateCacheStrategy(
|
||||
new DoctrineCacheStorage(
|
||||
new FilesystemCache('/tmp/')
|
||||
new FlysystemStorage(
|
||||
new LocalFilesystemAdapter('/tmp/')
|
||||
)
|
||||
)
|
||||
),
|
||||
@@ -178,10 +136,8 @@ $stack->push(
|
||||
$stack->push(
|
||||
new CacheMiddleware(
|
||||
new PublicCacheStrategy(
|
||||
new DoctrineCacheStorage(
|
||||
new PredisCache(
|
||||
new Predis\Client('tcp://10.0.0.1:6379')
|
||||
)
|
||||
new Psr6CacheStorage(
|
||||
new ArrayCachePool()
|
||||
)
|
||||
)
|
||||
),
|
||||
@@ -197,16 +153,16 @@ disregarding any possibly present caching headers:
|
||||
[...]
|
||||
use Kevinrob\GuzzleCache\KeyValueHttpHeader;
|
||||
use Kevinrob\GuzzleCache\Strategy\GreedyCacheStrategy;
|
||||
use Kevinrob\GuzzleCache\Storage\DoctrineCacheStorage;
|
||||
use Doctrine\Common\Cache\FilesystemCache;
|
||||
use Kevinrob\GuzzleCache\Storage\FlysystemStorage;
|
||||
use League\Flysystem\Local\LocalFilesystemAdapter;
|
||||
|
||||
[...]
|
||||
// Greedy caching
|
||||
$stack->push(
|
||||
new CacheMiddleware(
|
||||
new GreedyCacheStrategy(
|
||||
new DoctrineCacheStorage(
|
||||
new FilesystemCache('/tmp/')
|
||||
new FlysystemStorage(
|
||||
new LocalFilesystemAdapter('/tmp/')
|
||||
),
|
||||
1800, // the TTL in seconds
|
||||
new KeyValueHttpHeader(['Authorization']) // Optional - specify the headers that can change the cache key
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "kevinrob/guzzle-cache-middleware",
|
||||
"type": "library",
|
||||
"description": "A HTTP/1.1 Cache for Guzzle 6. It's a simple Middleware to be added in the HandlerStack. (RFC 7234)",
|
||||
"keywords": ["guzzle", "guzzle6", "cache", "http", "http 1.1", "psr6", "psr7", "handler", "middleware", "cache-control", "rfc7234", "performance", "php", "promise", "expiration", "validation", "Etag", "flysystem", "doctrine"],
|
||||
"keywords": ["guzzle", "guzzle6", "cache", "http", "http 1.1", "psr6", "psr7", "handler", "middleware", "cache-control", "rfc7234", "performance", "php", "promise", "expiration", "validation", "Etag", "flysystem"],
|
||||
"homepage": "https://github.com/Kevinrob/guzzle-cache-middleware",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
@@ -20,8 +20,7 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.6.21",
|
||||
"doctrine/cache": "^1.10",
|
||||
"league/flysystem": "^2.5",
|
||||
"league/flysystem": "^3.16",
|
||||
"psr/cache": "^1.0",
|
||||
"cache/array-adapter": "^0.4 || ^0.5 || ^1.0",
|
||||
"illuminate/cache": "^5.0",
|
||||
@@ -41,7 +40,6 @@
|
||||
},
|
||||
"suggest": {
|
||||
"guzzlehttp/guzzle": "For using this library. It was created for Guzzle6 (but you can use it with any PSR-7 HTTP client).",
|
||||
"doctrine/cache": "This library has a lot of ready-to-use cache storage (to be used with Kevinrob\\GuzzleCache\\Storage\\DoctrineCacheStorage). Use only versions >=1.4.0 < 2.0.0",
|
||||
"league/flysystem": "To be used with Kevinrob\\GuzzleCache\\Storage\\FlysystemStorage",
|
||||
"psr/cache": "To be used with Kevinrob\\GuzzleCache\\Storage\\Psr6CacheStorage",
|
||||
"psr/simple-cache": "To be used with Kevinrob\\GuzzleCache\\Storage\\Psr16CacheStorage",
|
||||
|
||||
@@ -1 +1 @@
|
||||
See instructions in lib/guzzlehttp/readme_moodle.md
|
||||
See instructions in public/lib/guzzlehttp/readme_moodle.md
|
||||
|
||||
@@ -19,7 +19,7 @@ class BodyStore
|
||||
public function __construct(string $body)
|
||||
{
|
||||
$this->body = $body;
|
||||
$this->toRead = mb_strlen($this->body);
|
||||
$this->toRead = strlen($this->body);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -34,7 +34,7 @@ class BodyStore
|
||||
|
||||
$length = min($length, $this->toRead);
|
||||
|
||||
$body = mb_substr(
|
||||
$body = substr(
|
||||
$this->body,
|
||||
$this->read,
|
||||
$length
|
||||
|
||||
@@ -302,7 +302,7 @@ class CacheEntry implements \Serializable
|
||||
new PumpStream(
|
||||
new BodyStore($bodyString),
|
||||
[
|
||||
'size' => mb_strlen($bodyString),
|
||||
'size' => strlen($bodyString),
|
||||
]
|
||||
)
|
||||
);
|
||||
|
||||
-74
@@ -1,74 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Kevinrob\GuzzleCache\Storage;
|
||||
|
||||
use Doctrine\Common\Cache\Cache;
|
||||
use Kevinrob\GuzzleCache\CacheEntry;
|
||||
|
||||
class CompressedDoctrineCacheStorage implements CacheStorageInterface
|
||||
{
|
||||
/**
|
||||
* @var Cache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* @param Cache $cache
|
||||
*/
|
||||
public function __construct(Cache $cache)
|
||||
{
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetch($key)
|
||||
{
|
||||
try {
|
||||
$cache = unserialize(gzuncompress($this->cache->fetch($key)));
|
||||
if ($cache instanceof CacheEntry) {
|
||||
return $cache;
|
||||
}
|
||||
} catch (\Exception $ignored) {
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function save($key, CacheEntry $data)
|
||||
{
|
||||
try {
|
||||
$lifeTime = $data->getTTL();
|
||||
if ($lifeTime >= 0) {
|
||||
return $this->cache->save(
|
||||
$key,
|
||||
gzcompress(serialize($data)),
|
||||
$lifeTime
|
||||
);
|
||||
}
|
||||
} catch (\Exception $ignored) {
|
||||
// No fail if we can't save it the storage
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
try {
|
||||
return $this->cache->delete($key);
|
||||
} catch (\Exception $ignored) {
|
||||
// Don't fail if we can't delete it
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Kevinrob\GuzzleCache\Storage;
|
||||
|
||||
use Doctrine\Common\Cache\Cache;
|
||||
use Kevinrob\GuzzleCache\CacheEntry;
|
||||
|
||||
class DoctrineCacheStorage implements CacheStorageInterface
|
||||
{
|
||||
/**
|
||||
* @var Cache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* @param Cache $cache
|
||||
*/
|
||||
public function __construct(Cache $cache)
|
||||
{
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetch($key)
|
||||
{
|
||||
try {
|
||||
$cache = unserialize($this->cache->fetch($key));
|
||||
if ($cache instanceof CacheEntry) {
|
||||
return $cache;
|
||||
}
|
||||
} catch (\Exception $ignored) {
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function save($key, CacheEntry $data)
|
||||
{
|
||||
try {
|
||||
$lifeTime = $data->getTTL();
|
||||
if ($lifeTime >= 0) {
|
||||
return $this->cache->save(
|
||||
$key,
|
||||
serialize($data),
|
||||
$lifeTime
|
||||
);
|
||||
}
|
||||
} catch (\Exception $ignored) {
|
||||
// No fail if we can't save it the storage
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
try {
|
||||
return $this->cache->delete($key);
|
||||
} catch (\Exception $ignored) {
|
||||
// Don't fail if we can't delete it
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -58,8 +58,7 @@ class FlysystemStorage implements CacheStorageInterface
|
||||
public function delete($key)
|
||||
{
|
||||
try {
|
||||
$this->filesystem->delete($key);
|
||||
return true;
|
||||
return $this->filesystem->delete($key);
|
||||
} catch (FilesystemException $ex) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -117,6 +117,6 @@ class GreedyCacheStrategy extends PrivateCacheStrategy
|
||||
*/
|
||||
public function delete(RequestInterface $request)
|
||||
{
|
||||
return $this->storage->delete($this->getCacheKey($request));
|
||||
return $this->storage->delete($this->getCacheKey($request, $this->varyHeaders));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,18 @@ class PublicCacheStrategy extends PrivateCacheStrategy
|
||||
return;
|
||||
}
|
||||
|
||||
// RFC 9111 Section 3.5: Check Authorization header caching restrictions for shared caches
|
||||
if ($request->hasHeader('Authorization')) {
|
||||
// Requests with Authorization header should only be cached if response contains
|
||||
// one of the following directives: public, must-revalidate, s-maxage
|
||||
if (!$cacheControl->has('public')
|
||||
&& !$cacheControl->has('must-revalidate')
|
||||
&& !$cacheControl->has('s-maxage')) {
|
||||
// No explicit authorization to cache authenticated requests
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return parent::getCacheObject($request, $response);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,27 @@
|
||||
# CHANGELOG
|
||||
|
||||
|
||||
## 2.3.0 - 2025-08-22
|
||||
|
||||
### Added
|
||||
|
||||
- PHP 8.5 support
|
||||
|
||||
|
||||
## 2.2.0 - 2025-03-27
|
||||
|
||||
### Fixed
|
||||
|
||||
- Revert "Allow an empty EachPromise to be resolved by running the queue"
|
||||
|
||||
|
||||
## 2.1.0 - 2025-03-27
|
||||
|
||||
### Added
|
||||
|
||||
- Allow an empty EachPromise to be resolved by running the queue
|
||||
|
||||
|
||||
## 2.0.4 - 2024-10-17
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -41,7 +41,7 @@ composer require guzzlehttp/promises
|
||||
| Version | Status | PHP Version |
|
||||
|---------|---------------------|--------------|
|
||||
| 1.x | Security fixes only | >=5.5,<8.3 |
|
||||
| 2.x | Latest | >=7.2.5,<8.5 |
|
||||
| 2.x | Latest | >=7.2.5,<8.6 |
|
||||
|
||||
|
||||
## Quick Start
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"bamarni/composer-bin-plugin": "^1.8.2",
|
||||
"phpunit/phpunit": "^8.5.39 || ^9.6.20"
|
||||
"phpunit/phpunit": "^8.5.44 || ^9.6.25"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
||||
@@ -1 +1 @@
|
||||
See instructions in lib/guzzlehttp/readme_moodle.md
|
||||
See instructions in public/lib/guzzlehttp/readme_moodle.md
|
||||
|
||||
@@ -5,6 +5,26 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## 2.8.0 - 2025-08-23
|
||||
|
||||
### Added
|
||||
|
||||
- Allow empty lists as header values
|
||||
|
||||
### Changed
|
||||
|
||||
- PHP 8.5 support
|
||||
|
||||
## 2.7.1 - 2025-03-27
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed uppercase IPv6 addresses in URI
|
||||
|
||||
### Changed
|
||||
|
||||
- Improve uploaded file error message
|
||||
|
||||
## 2.7.0 - 2024-07-18
|
||||
|
||||
### Added
|
||||
|
||||
@@ -25,7 +25,7 @@ composer require guzzlehttp/psr7
|
||||
| Version | Status | PHP Version |
|
||||
|---------|---------------------|--------------|
|
||||
| 1.x | EOL (2024-06-30) | >=5.4,<8.2 |
|
||||
| 2.x | Latest | >=7.2.5,<8.5 |
|
||||
| 2.x | Latest | >=7.2.5,<8.6 |
|
||||
|
||||
|
||||
## AppendStream
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
"require-dev": {
|
||||
"bamarni/composer-bin-plugin": "^1.8.2",
|
||||
"http-interop/http-factory-tests": "0.9.0",
|
||||
"phpunit/phpunit": "^8.5.39 || ^9.6.20"
|
||||
"phpunit/phpunit": "^8.5.44 || ^9.6.25"
|
||||
},
|
||||
"suggest": {
|
||||
"laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
|
||||
|
||||
@@ -1 +1 @@
|
||||
See instructions in lib/guzzlehttp/readme_moodle.md
|
||||
See instructions in public/lib/guzzlehttp/readme_moodle.md
|
||||
|
||||
@@ -174,10 +174,6 @@ trait MessageTrait
|
||||
return $this->trimAndValidateHeaderValues([$value]);
|
||||
}
|
||||
|
||||
if (count($value) === 0) {
|
||||
throw new \InvalidArgumentException('Header value can not be an empty array.');
|
||||
}
|
||||
|
||||
return $this->trimAndValidateHeaderValues($value);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,15 +11,15 @@ use RuntimeException;
|
||||
|
||||
class UploadedFile implements UploadedFileInterface
|
||||
{
|
||||
private const ERRORS = [
|
||||
UPLOAD_ERR_OK,
|
||||
UPLOAD_ERR_INI_SIZE,
|
||||
UPLOAD_ERR_FORM_SIZE,
|
||||
UPLOAD_ERR_PARTIAL,
|
||||
UPLOAD_ERR_NO_FILE,
|
||||
UPLOAD_ERR_NO_TMP_DIR,
|
||||
UPLOAD_ERR_CANT_WRITE,
|
||||
UPLOAD_ERR_EXTENSION,
|
||||
private const ERROR_MAP = [
|
||||
UPLOAD_ERR_OK => 'UPLOAD_ERR_OK',
|
||||
UPLOAD_ERR_INI_SIZE => 'UPLOAD_ERR_INI_SIZE',
|
||||
UPLOAD_ERR_FORM_SIZE => 'UPLOAD_ERR_FORM_SIZE',
|
||||
UPLOAD_ERR_PARTIAL => 'UPLOAD_ERR_PARTIAL',
|
||||
UPLOAD_ERR_NO_FILE => 'UPLOAD_ERR_NO_FILE',
|
||||
UPLOAD_ERR_NO_TMP_DIR => 'UPLOAD_ERR_NO_TMP_DIR',
|
||||
UPLOAD_ERR_CANT_WRITE => 'UPLOAD_ERR_CANT_WRITE',
|
||||
UPLOAD_ERR_EXTENSION => 'UPLOAD_ERR_EXTENSION',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -104,7 +104,7 @@ class UploadedFile implements UploadedFileInterface
|
||||
*/
|
||||
private function setError(int $error): void
|
||||
{
|
||||
if (false === in_array($error, UploadedFile::ERRORS, true)) {
|
||||
if (!isset(UploadedFile::ERROR_MAP[$error])) {
|
||||
throw new InvalidArgumentException(
|
||||
'Invalid error status for UploadedFile'
|
||||
);
|
||||
@@ -137,7 +137,7 @@ class UploadedFile implements UploadedFileInterface
|
||||
private function validateActive(): void
|
||||
{
|
||||
if (false === $this->isOk()) {
|
||||
throw new RuntimeException('Cannot retrieve stream due to upload error');
|
||||
throw new RuntimeException(\sprintf('Cannot retrieve stream due to upload error (%s)', self::ERROR_MAP[$this->error]));
|
||||
}
|
||||
|
||||
if ($this->isMoved()) {
|
||||
|
||||
@@ -107,7 +107,7 @@ class Uri implements UriInterface, \JsonSerializable
|
||||
{
|
||||
// If IPv6
|
||||
$prefix = '';
|
||||
if (preg_match('%^(.*://\[[0-9:a-f]+\])(.*?)$%', $url, $matches)) {
|
||||
if (preg_match('%^(.*://\[[0-9:a-fA-F]+\])(.*?)$%', $url, $matches)) {
|
||||
/** @var array{0:string, 1:string, 2:string} $matches */
|
||||
$prefix = $matches[1];
|
||||
$url = $matches[2];
|
||||
|
||||
@@ -397,7 +397,7 @@ final class Utils
|
||||
restore_error_handler();
|
||||
|
||||
if ($ex) {
|
||||
/** @var $ex \RuntimeException */
|
||||
/** @var \RuntimeException $ex */
|
||||
throw $ex;
|
||||
}
|
||||
|
||||
@@ -444,7 +444,7 @@ final class Utils
|
||||
restore_error_handler();
|
||||
|
||||
if ($ex) {
|
||||
/** @var $ex \RuntimeException */
|
||||
/** @var \RuntimeException $ex */
|
||||
throw $ex;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,18 +8,18 @@ cd "$installdir"
|
||||
composer require guzzlehttp/guzzle kevinrob/guzzle-cache-middleware
|
||||
|
||||
cd -
|
||||
rm -rf lib/guzzlehttp/guzzle lib/guzzlehttp/psr7 lib/guzzlehttp/promises lib/guzzlehttp/kevinrob/guzzlecache
|
||||
cp -rf "$installdir"/vendor/guzzlehttp/guzzle lib/guzzlehttp/guzzle
|
||||
cp -rf "$installdir"/vendor/guzzlehttp/psr7 lib/guzzlehttp/psr7
|
||||
cp -rf "$installdir"/vendor/guzzlehttp/promises lib/guzzlehttp/promises
|
||||
cp -rf "$installdir"/vendor/kevinrob/guzzle-cache-middleware lib/guzzlehttp/kevinrob/guzzlecache
|
||||
rm -rf lib/guzzlehttp/kevinrob/guzzlecache/*.png
|
||||
rm -rf public/lib/guzzlehttp/guzzle public/lib/guzzlehttp/psr7 public/lib/guzzlehttp/promises public/lib/guzzlehttp/kevinrob/guzzlecache
|
||||
cp -rf "$installdir"/vendor/guzzlehttp/guzzle public/lib/guzzlehttp/guzzle
|
||||
cp -rf "$installdir"/vendor/guzzlehttp/psr7 public/lib/guzzlehttp/psr7
|
||||
cp -rf "$installdir"/vendor/guzzlehttp/promises public/lib/guzzlehttp/promises
|
||||
cp -rf "$installdir"/vendor/kevinrob/guzzle-cache-middleware public/lib/guzzlehttp/kevinrob/guzzlecache
|
||||
rm -rf public/lib/guzzlehttp/kevinrob/guzzlecache/*.png
|
||||
|
||||
echo "See instructions in lib/guzzlehttp/readme_moodle.md" > lib/guzzlehttp/guzzle/readme_moodle.txt
|
||||
echo "See instructions in lib/guzzlehttp/readme_moodle.md" > lib/guzzlehttp/promises/readme_moodle.txt
|
||||
echo "See instructions in lib/guzzlehttp/readme_moodle.md" > lib/guzzlehttp/psr7/readme_moodle.txt
|
||||
echo "See instructions in lib/guzzlehttp/readme_moodle.md" > lib/guzzlehttp/kevinrob/guzzlecache/readme_moodle.txt
|
||||
git add lib/guzzlehttp/guzzle lib/guzzlehttp/psr7 lib/guzzlehttp/promises
|
||||
echo "See instructions in public/lib/guzzlehttp/readme_moodle.md" > public/lib/guzzlehttp/guzzle/readme_moodle.txt
|
||||
echo "See instructions in public/lib/guzzlehttp/readme_moodle.md" > public/lib/guzzlehttp/promises/readme_moodle.txt
|
||||
echo "See instructions in public/lib/guzzlehttp/readme_moodle.md" > public/lib/guzzlehttp/psr7/readme_moodle.txt
|
||||
echo "See instructions in public/lib/guzzlehttp/readme_moodle.md" > public/lib/guzzlehttp/kevinrob/guzzlecache/readme_moodle.txt
|
||||
git add public/lib/guzzlehttp/guzzle public/lib/guzzlehttp/psr7 public/lib/guzzlehttp/promises public/lib/guzzlehttp/kevinrob
|
||||
```
|
||||
|
||||
Now update `lib/thirdpartylibs.xml`
|
||||
Now update `public/lib/thirdpartylibs.xml`
|
||||
|
||||
@@ -718,7 +718,7 @@ All rights reserved.</copyright>
|
||||
<location>guzzlehttp/guzzle</location>
|
||||
<name>GuzzleHttp/Guzzle</name>
|
||||
<description>Guzzle is a PHP HTTP client library</description>
|
||||
<version>7.9.2</version>
|
||||
<version>7.10.0</version>
|
||||
<license>MIT</license>
|
||||
<repository>https://github.com/guzzle/guzzle</repository>
|
||||
</library>
|
||||
@@ -726,7 +726,7 @@ All rights reserved.</copyright>
|
||||
<location>guzzlehttp/promises</location>
|
||||
<name>GuzzleHttp/Promises</name>
|
||||
<description>Guzzle promises library</description>
|
||||
<version>2.0.4</version>
|
||||
<version>2.3.0</version>
|
||||
<license>MIT</license>
|
||||
<repository>https://github.com/guzzle/promises</repository>
|
||||
</library>
|
||||
@@ -742,7 +742,7 @@ All rights reserved.</copyright>
|
||||
<location>guzzlehttp/psr7</location>
|
||||
<name>GuzzleHttp/PSR7</name>
|
||||
<description>PSR-7 message implementation that also provides common utility methods</description>
|
||||
<version>2.7.0</version>
|
||||
<version>2.8.0</version>
|
||||
<license>MIT</license>
|
||||
<repository>https://github.com/guzzle/psr7</repository>
|
||||
</library>
|
||||
@@ -758,7 +758,7 @@ All rights reserved.</copyright>
|
||||
<location>guzzlehttp/kevinrob/guzzlecache</location>
|
||||
<name>Guzzle cache middleware</name>
|
||||
<description>A HTTP Cache for Guzzle as a simple Middleware to be added in the HandlerStack.</description>
|
||||
<version>6.0.0</version>
|
||||
<version>7.0.0</version>
|
||||
<license>MIT</license>
|
||||
<repository>https://github.com/Kevinrob/guzzle-cache-middleware</repository>
|
||||
</library>
|
||||
|
||||
Reference in New Issue
Block a user