Skip to content

merge 2.x to 3.x #649

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Changelog

* If a custom proxy client is configured on the cache manager, the `ProxyClient` class is an alias to that client, to support autowiring.
* Attribute configuration now also works on single action controllers with the `__invoke` method.
* New configuration option `proxy_client.*.http.request_factory` and `stream_factory` to support custom PSR-17 HTTP request and stream factories for proxy clients.

3.1.2
-----
Expand Down Expand Up @@ -53,6 +54,11 @@ Changelog
2.x
===

2.18.0
------

* New configuration option `proxy_client.*.http.request_factory` to support custom HTTP request factories for proxy clients.

2.17.1
------

Expand Down
3 changes: 2 additions & 1 deletion Resources/doc/features/invalidation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ To refresh paths and routes, you can use ``refreshPath($path, $headers)`` and

If you want to add a header (such as ``Authorization``) to *all*
invalidation requests, you can use a
:ref:`custom HTTP client <custom HTTP client>` instead.
:ref:`custom HTTP client <custom HTTP client>` or
:ref:`custom HTTP request factory <custom HTTP request factory>` instead.

.. _invalidation configuration:

Expand Down
17 changes: 17 additions & 0 deletions Resources/doc/reference/configuration/proxy-client.rst
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,23 @@ example to send a basic authentication header with each request, you can
configure a service for the ``HttpClient`` and specify that in the
``http_client`` option of any of the cache proxy clients.

.. _custom HTTP request factory:

Custom HTTP Request Factory and Stream Factory
----------------------------------------------

The proxy client uses an implementation of PSR-17 ``Psr\Http\Message\RequestFactoryInterface``
to create HTTP requests and ``Psr\Http\Message\StreamFactoryInterface`` to
create streams.

If you need to customize request creation, you can configure your custom
service and specify that in the ``request_factory`` option of any of the cache
proxy clients.

If you need to customize stream creation, you can configure your custom service
and specify that in the ``stream_factory`` option of any of the cache proxy
clients.

Caching Proxy Configuration
---------------------------

Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
],
"require": {
"php": "^8.1",
"friendsofsymfony/http-cache": "^2.15 || ^3.0",
"friendsofsymfony/http-cache": "^3.0",
"symfony/dependency-injection": "^6.4 || ^7.0",
"symfony/expression-language": "^6.4 || ^7.0",
"symfony/framework-bundle": "^6.4 || ^7.0",
Expand Down Expand Up @@ -60,7 +60,7 @@
"phpstan/phpstan": "^2",
"phpstan/phpstan-symfony": "^2",
"phpstan/extension-installer": "^1.4",
"jean-beru/fos-http-cache-cloudfront": "^1.1",
"jean-beru/fos-http-cache-cloudfront": "^1.1.1",
"friendsofphp/php-cs-fixer": "^3.54"
},
"suggest": {
Expand Down
8 changes: 8 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,14 @@ private function getHttpDispatcherNode(): ArrayNodeDefinition
->defaultNull()
->info('Httplug async client service name to use for sending the requests.')
->end()
->scalarNode('request_factory')
->defaultNull()
->info('Service name of PSR-17 message factory.')
->end()
->scalarNode('stream_factory')
->defaultNull()
->info('Service name of PSR-17 stream factory.')
->end()
->end()
;

Expand Down
60 changes: 60 additions & 0 deletions src/DependencyInjection/FOSHttpCacheExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,18 @@ private function loadVarnish(ContainerBuilder $container, XmlFileLoader $loader,
$container->setParameter('fos_http_cache.proxy_client.varnish.options', $options);

$loader->load('varnish.xml');

$requestFactory = isset($config['http']['request_factory'])
? new Reference($config['http']['request_factory'])
: null;
$container->getDefinition('fos_http_cache.proxy_client.varnish')
->replaceArgument(2, $requestFactory);

$streamFactory = isset($config['http']['stream_factory'])
? new Reference($config['http']['stream_factory'])
: null;
$container->getDefinition('fos_http_cache.proxy_client.varnish')
->replaceArgument(3, $streamFactory);
}

private function loadNginx(ContainerBuilder $container, XmlFileLoader $loader, array $config): void
Expand All @@ -436,6 +448,18 @@ private function loadNginx(ContainerBuilder $container, XmlFileLoader $loader, a
'purge_location' => $config['purge_location'],
]);
$loader->load('nginx.xml');

$requestFactory = isset($config['http']['request_factory'])
? new Reference($config['http']['request_factory'])
: null;
$container->getDefinition('fos_http_cache.proxy_client.nginx')
->replaceArgument(2, $requestFactory);

$streamFactory = isset($config['http']['stream_factory'])
? new Reference($config['http']['stream_factory'])
: null;
$container->getDefinition('fos_http_cache.proxy_client.nginx')
->replaceArgument(3, $streamFactory);
}

private function loadSymfony(ContainerBuilder $container, XmlFileLoader $loader, array $config): void
Expand All @@ -462,6 +486,18 @@ private function loadSymfony(ContainerBuilder $container, XmlFileLoader $loader,
$container->setParameter('fos_http_cache.proxy_client.symfony.options', $options);

$loader->load('symfony.xml');

$requestFactory = isset($config['http']['request_factory'])
? new Reference($config['http']['request_factory'])
: null;
$container->getDefinition('fos_http_cache.proxy_client.symfony')
->replaceArgument(2, $requestFactory);

$streamFactory = isset($config['http']['stream_factory'])
? new Reference($config['http']['stream_factory'])
: null;
$container->getDefinition('fos_http_cache.proxy_client.symfony')
->replaceArgument(3, $streamFactory);
}

private function loadCloudflare(ContainerBuilder $container, XmlFileLoader $loader, array $config): void
Expand All @@ -475,6 +511,18 @@ private function loadCloudflare(ContainerBuilder $container, XmlFileLoader $load
$container->setParameter('fos_http_cache.proxy_client.cloudflare.options', $options);

$loader->load('cloudflare.xml');

$requestFactory = isset($config['http']['request_factory'])
? new Reference($config['http']['request_factory'])
: null;
$container->getDefinition('fos_http_cache.proxy_client.cloudflare')
->replaceArgument(2, $requestFactory);

$streamFactory = isset($config['http']['stream_factory'])
? new Reference($config['http']['stream_factory'])
: null;
$container->getDefinition('fos_http_cache.proxy_client.cloudflare')
->replaceArgument(3, $streamFactory);
}

private function loadCloudfront(ContainerBuilder $container, XmlFileLoader $loader, array $config): void
Expand Down Expand Up @@ -511,6 +559,18 @@ private function loadFastly(ContainerBuilder $container, XmlFileLoader $loader,
$container->setParameter('fos_http_cache.proxy_client.fastly.options', $options);

$loader->load('fastly.xml');

$requestFactory = isset($config['http']['request_factory'])
? new Reference($config['http']['request_factory'])
: null;
$container->getDefinition('fos_http_cache.proxy_client.fastly')
->replaceArgument(2, $requestFactory);

$streamFactory = isset($config['http']['stream_factory'])
? new Reference($config['http']['stream_factory'])
: null;
$container->getDefinition('fos_http_cache.proxy_client.fastly')
->replaceArgument(3, $streamFactory);
}

/**
Expand Down
2 changes: 2 additions & 0 deletions src/Resources/config/cloudflare.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
lazy="true">
<argument type="service" id="fos_http_cache.proxy_client.cloudflare.http_dispatcher"/>
<argument>%fos_http_cache.proxy_client.cloudflare.options%</argument>
<argument /> <!-- request factory -->
<argument /> <!-- stream factory -->
</service>
</services>

Expand Down
2 changes: 2 additions & 0 deletions src/Resources/config/fastly.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
lazy="true">
<argument type="service" id="fos_http_cache.proxy_client.fastly.http_dispatcher"/>
<argument>%fos_http_cache.proxy_client.fastly.options%</argument>
<argument /> <!-- request factory -->
<argument /> <!-- stream factory -->
</service>
</services>

Expand Down
2 changes: 2 additions & 0 deletions src/Resources/config/nginx.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
public="true">
<argument type="service" id="fos_http_cache.proxy_client.nginx.http_dispatcher"/>
<argument>%fos_http_cache.proxy_client.nginx.options%</argument>
<argument /> <!-- request factory -->
<argument /> <!-- stream factory -->
</service>
</services>

Expand Down
2 changes: 2 additions & 0 deletions src/Resources/config/symfony.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
public="true">
<argument type="service" id="fos_http_cache.proxy_client.symfony.http_dispatcher"/>
<argument>%fos_http_cache.proxy_client.symfony.options%</argument>
<argument /> <!-- request factory -->
<argument /> <!-- stream factory -->
</service>
</services>

Expand Down
2 changes: 2 additions & 0 deletions src/Resources/config/varnish.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
public="true">
<argument type="service" id="fos_http_cache.proxy_client.varnish.http_dispatcher"/>
<argument>%fos_http_cache.proxy_client.varnish.options%</argument>
<argument /> <!-- request factory -->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could use a new Symfony 5.1 feature here: https://symfony.com/blog/new-in-symfony-5-1-abstract-service-arguments

I don't know what your strategy with this this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah right, that is a thing now. but as null is a valid argument here, i would keep this as is.

<argument /> <!-- stream factory -->
</service>
</services>

Expand Down
16 changes: 16 additions & 0 deletions tests/Unit/DependencyInjection/ConfigurationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ public function testSupportsAllConfigFormats(): void
'servers' => ['22.22.22.22'],
'base_url' => '/test',
'http_client' => 'acme.guzzle.varnish',
'request_factory' => null,
'stream_factory' => null,
],
],
],
Expand Down Expand Up @@ -241,6 +243,8 @@ public function testSupportsNginx(): void
'servers' => ['22.22.22.22'],
'base_url' => '/test',
'http_client' => 'acme.guzzle.nginx',
'request_factory' => null,
'stream_factory' => null,
],
],
];
Expand Down Expand Up @@ -276,6 +280,8 @@ public function testSupportsSymfony(): void
'servers' => ['22.22.22.22'],
'base_url' => '/test',
'http_client' => 'acme.guzzle.symfony',
'request_factory' => null,
'stream_factory' => null,
],
'use_kernel_dispatcher' => false,
],
Expand Down Expand Up @@ -506,6 +512,8 @@ public function testSplitOptions(): void
'base_url' => null,
'http_client' => null,
'servers' => ['1.1.1.1:80', '2.2.2.2:80'],
'request_factory' => null,
'stream_factory' => null,
],
'tags_header' => 'X-Cache-Tags',
'tag_mode' => 'ban',
Expand All @@ -516,6 +524,8 @@ public function testSplitOptions(): void
'base_url' => null,
'http_client' => null,
'servers' => ['1.1.1.1:81', '2.2.2.2:81'],
'request_factory' => null,
'stream_factory' => null,
],
],
];
Expand Down Expand Up @@ -757,6 +767,8 @@ public function testUserContextLogoutHandler(string $configFile, $expected, $cac
'servers' => ['localhost'],
'base_url' => null,
'http_client' => null,
'request_factory' => null,
'stream_factory' => null,
];
$expectedConfiguration['proxy_client'][$proxyClient]['purge_location'] = false;
}
Expand Down Expand Up @@ -796,6 +808,8 @@ public function testSupportsServersFromJsonEnv(): void
'servers_from_jsonenv' => '%env(json:VARNISH_SERVERS)%',
'base_url' => '/test',
'http_client' => 'acme.guzzle.nginx',
'request_factory' => null,
'stream_factory' => null,
],
'tag_mode' => 'ban',
'tags_header' => 'X-Cache-Tags',
Expand Down Expand Up @@ -829,6 +843,8 @@ public function testConfigureExpressionLanguageService(): void
'servers_from_jsonenv' => '%env(json:VARNISH_SERVERS)%',
'base_url' => '/test',
'http_client' => 'acme.guzzle.nginx',
'request_factory' => null,
'stream_factory' => null,
],
'tag_mode' => 'ban',
'tags_header' => 'X-Cache-Tags',
Expand Down
Loading