diff --git a/Resources/doc/reference/configuration/headers.rst b/Resources/doc/reference/configuration/headers.rst index d8e2b127..de7e71a9 100644 --- a/Resources/doc/reference/configuration/headers.rst +++ b/Resources/doc/reference/configuration/headers.rst @@ -347,6 +347,39 @@ section: This example adds the header ``X-Reverse-Proxy-TTL: 3600`` to your responses. +``reverse_proxy_cache_control`` +""""""""""""""""""""" + +**type**: ``array`` + +The map under ``reverse_proxy_cache_control`` goes with ``ttl_header``. +The names are specified with underscores in yaml, but translated to ``-`` for +the ``X-Reverse-Proxy-TTL`` header. + +You can use the standard cache control directives: + +* ``max_age`` time in seconds; +* ``s_maxage`` time in seconds for proxy caches (also public caches); +* ``private`` true or false; +* ``public`` true or false; + +.. code-block:: yaml + + # app/config/config.yml + fos_http_cache: + cache_control: + rules: + - + headers: + reverse_proxy_cache_control: + max_age: 36000 + public: true + cache_control: + no_store: true + private: true + +This example adds the header ``X-Reverse-Proxy-TTL: max-age=36000, public`` to your responses. + ``ttl_header`` -------------- diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 2b7ae1da..c644f372 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -337,6 +337,15 @@ private function addCacheControlSection(ArrayNodeDefinition $rootNode): void ->defaultNull() ->info('Specify a custom time to live in seconds for your caching proxy. This value is sent in the custom header configured in cache_control.ttl_header.') ->end() + ->arrayNode('reverse_proxy_cache_control') + ->info('Add the specified cache control directives for reverse proxy.') + ->children() + ->scalarNode('max_age')->end() + ->scalarNode('s_maxage')->end() + ->booleanNode('private')->end() + ->booleanNode('public')->end() + ->end() + ->end() ->arrayNode('vary') ->beforeNormalization()->ifString()->then(function ($v) { return preg_split('/\s*,\s*/', $v); diff --git a/src/EventListener/CacheControlListener.php b/src/EventListener/CacheControlListener.php index 5ecd47db..ccb87742 100644 --- a/src/EventListener/CacheControlListener.php +++ b/src/EventListener/CacheControlListener.php @@ -116,11 +116,30 @@ public function onKernelResponse(ResponseEvent $event): void } } - if (array_key_exists('reverse_proxy_ttl', $options) - && null !== $options['reverse_proxy_ttl'] - && !$response->headers->has($this->ttlHeader) - ) { - $response->headers->set($this->ttlHeader, $options['reverse_proxy_ttl'], false); + if (!$response->headers->has($this->ttlHeader)) { + if (!empty($options['reverse_proxy_cache_control'])) { + $directives = array_intersect_key($options['reverse_proxy_cache_control'], $this->supportedDirectives); + + if (!empty($directives)) { + $headerValues = []; + + foreach ($directives as $k => $v) { + $k = str_replace('_', '-', $k); + + if (in_array($k, ['public', 'private'])) { + if ($v) { + $headerValues[] = $k; + } + } else { + $headerValues[] = $k . '=' . $v; + } + } + + $response->headers->set($this->ttlHeader, \implode(', ', $headerValues), false); + } + } elseif (array_key_exists('reverse_proxy_ttl', $options) && null !== $options['reverse_proxy_ttl']) { + $response->headers->set($this->ttlHeader, $options['reverse_proxy_ttl'], false); + } } if (!empty($options['vary'])) {