Skip to content
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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Changelog
=========

1.2.0
-----

* **2014-12-05** Added support for the symfony/http-kernel component reverse proxy HttpCache.

1.1.2
-----

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ Features
* Send [cache invalidation requests](http://foshttpcache.readthedocs.org/en/latest/cache-invalidator.html)
with minimal impact on performance.
* Use the built-in support for [Varnish](http://foshttpcache.readthedocs.org/en/latest/varnish-configuration.html)
3 and 4, [Nginx](http://foshttpcache.readthedocs.org/en/latest/nginx-configuration.html)
3 and 4, [Nginx](http://foshttpcache.readthedocs.org/en/latest/nginx-configuration.html), the
[Symfony reverse proxy from the http-kernel component](http://foshttpcache.readthedocs.org/en/latest/symfony-cache-configuration.html)
or easily implement your own caching proxy client.
* [Test your application](http://foshttpcache.readthedocs.org/en/latest/testing-your-application.html)
against your Varnish or Nginx setup.
Expand Down
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
"guzzle/plugin-mock": "*",
"mockery/mockery": "*",
"monolog/monolog": "*",
"symfony/process": "~2.3"
"symfony/process": "~2.3",
"symfony/http-kernel": "~2.3"
},
"suggest": {
"monolog/monolog": "For logging issues while invalidating"
Expand All @@ -42,7 +43,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
"dev-master": "1.2.x-dev"
}
}
}
11 changes: 6 additions & 5 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ FOSHttpCache
This is the documentation for the `FOSHttpCache library <https://github.com/FriendsOfSymfony/FOSHttpCache>`_.

This library integrates your PHP applications with HTTP caching proxies such as
Varnish. Use this library to send invalidation requests from your application
to the caching proxy and to test your caching and invalidation setup.
Varnish, Nginx or the Symfony HttpCache class. Use this library to send
invalidation requests from your application to the caching proxy and to test
your caching and invalidation setup.

If you use Symfony2, have a look at the FOSHttpCacheBundle_. The bundle
provides the Invalidator as a service, support for the built-in cache kernel of
Symfony and a number of Symfony2-specific features to help with caching and
If you use the Symfony2 full stack framework, have a look at the FOSHttpCacheBundle_.
Copy link
Member

Choose a reason for hiding this comment

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

👍

The bundle provides the Invalidator as a service, support for the built-in cache
kernel of Symfony and a number of Symfony2-specific features to help with caching and
caching proxies.

Contents:
Expand Down
2 changes: 1 addition & 1 deletion doc/proxy-clients.rst
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ Varnish client::
));

Make sure to add any headers that you want to ban on to your
:doc:`Varnish configuration <varnish-configuration>`.
:doc:`proxy configuration <proxy-configuration>`.

.. _custom guzzle client:

Expand Down
1 change: 1 addition & 0 deletions doc/proxy-configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ know about the other features of the caching proxy to get everything right.

varnish-configuration
nginx-configuration
symfony-cache-configuration
116 changes: 116 additions & 0 deletions doc/symfony-cache-configuration.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
Symfony HttpCache Configuration
-------------------------------

The ``symfony/http-kernel`` component provides a reverse proxy implemented
completely in PHP, called `HttpCache`_. While it is certainly less efficient
than using Varnish or Nginx, it can still provide considerable performance
gains over an installation that is not cached at all. It can be useful for
running an application on shared hosting for instance.

You can use features of this library with the Symfony ``HttpCache``. The basic
concept is to use event subscribers on the HttpCache class.

.. note::

If you are using the full stack Symfony framework, have a look at the
HttpCache provided by the FOSHttpCacheBundle_ instead.

.. warning::

Symfony HttpCache support is currently limited to following features:

* User context

Extending the right HttpCache
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Instead of extending ``Symfony\Component\HttpKernel\HttpCache\HttpCache``, your
``AppCache`` should extend ``FOS\HttpCache\SymfonyCache\EventDispatchingHttpCache``.

.. tip::

If your class already needs to extend a different class, simply copy the
event handling code from the EventDispatchingHttpCache into your
``AppCache`` class. The drawback is that you need to manually check whether
you need to adjust your ``AppCache`` each time you update the FOSHttpCache
library.

Now that you have an event dispatching kernel, you can make it register the
subscribers you need. While you could do that from your bootstrap code, this is
not the recommended way. You would need to adjust every place you instantiate
the cache. Instead, overwrite the constructor of AppCache and register the
subscribers there. A simple cache will look like this::

require_once __DIR__.'/AppKernel.php';

use FOS\HttpCache\SymfonyCache\EventDispatchingHttpCache;
use FOS\HttpCache\SymfonyCache\UserContextSubscriber;

class AppCache extends EventDispatchingHttpCache
{
/**
* Overwrite constructor to register event subscribers for FOSHttpCache.
*/
public function __construct(HttpKernelInterface $kernel, $cacheDir = null)
{
parent::__construct($kernel, $cacheDir);

$this->addSubscriber(new UserContextSubscriber());
}
}

User Context
~~~~~~~~~~~~

To support :doc:`user context hashing <user-context>` you need to register the
``UserContextSubscriber``. If the default settings are right for you, you don't
need to do anything more. You can customize a number of options through the
constructor:

* **anonymous_hash**: Hash used for anonymous user. This is a performance
optimization to not do a backend request for users that are not logged in.

* **user_hash_accept_header**: Accept header value to be used to request the
user hash to the backend application. Must match the setup of the backend
application.

**default**: ``application/vnd.fos.user-context-hash``

* **user_hash_header**: Name of the header the user context hash will be stored
into. Must match the setup for the Vary header in the backend application.

**default**: ``X-User-Context-Hash``

* **user_hash_uri**: Target URI used in the request for user context hash
generation.

**default**: ``/_fos_user_context_hash``

* **user_hash_method**: HTTP Method used with the hash lookup request for user
context hash generation.

**default**: ``GET``

* **session_name_prefix**: Prefix for session cookies. Must match your PHP session configuration.

**default**: ``PHPSESSID``

.. warning::

If you have a customized session name, it is **very important** that this
constant matches it.
Session IDs are indeed used as keys to cache the generated use context hash.

Wrong session name will lead to unexpected results such as having the same
user context hash for every users,
or not having it cached at all (painful for performance.

Cleaning the Cookie Header
^^^^^^^^^^^^^^^^^^^^^^^^^^

By default, the UserContextSubscriber only sets the session cookie (according to
the ``session_name_prefix`` option) in the requests to the backend. If you need
a different behaviour, overwrite ``UserContextSubscriber::cleanupHashLookupRequest``
with your own logic.

.. _HttpCache: http://symfony.com/doc/current/book/http_cache.html#symfony-reverse-proxy
5 changes: 3 additions & 2 deletions doc/user-context.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ Caching on user context works as follows:
Proxy Client Configuration
--------------------------

Currently, user context caching is only supported by Varnish. See the
:ref:`Varnish Configuration <varnish user context>` on how to prepare Varnish properly.
Currently, user context caching is only supported by Varnish and by the Symfony
HttpCache. See the :ref:`Varnish Configuration <varnish user context>` or
:doc:`Symfony HttpCache Configuration <symfony-cache-configuration>`.

Calculating the User Context Hash
---------------------------------
Expand Down
92 changes: 92 additions & 0 deletions src/SymfonyCache/CacheEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

/*
* This file is part of the FOSHttpCache package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace FOS\HttpCache\SymfonyCache;

use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\HttpCache\HttpCache;

/**
* Event raised by the HttpCache kernel.
*
* @author David Buchmann <[email protected]>
*/
class CacheEvent extends Event
{
/**
* @var HttpCache
*/
private $kernel;

/**
* @var Request
*/
private $request;

/**
* @var Response
*/
private $response;

/**
* @param HttpCache $kernel The kernel raising with this event.
* @param Request $request The request being processed.
*/
public function __construct(HttpCache $kernel, Request $request)
{
$this->kernel = $kernel;
$this->request = $request;
}

/**
* Get the cache kernel that raised this event.
*
* @return HttpCache
*/
public function getKernel()
{
return $this->kernel;
}

/**
* Get the request that is being processed.
*
* @return Request
*/
public function getRequest()
{
return $this->request;
}

/**
* @return Response|null The response if one was set.
*/
public function getResponse()
{
return $this->response;
}

/**
* Sets a response to use instead of continuing to handle this request.
*
* Setting a response stops propagation of the event to further event handlers.
*
* @param Response $response
*/
public function setResponse(Response $response)
{
$this->response = $response;

$this->stopPropagation();
}
}
81 changes: 81 additions & 0 deletions src/SymfonyCache/EventDispatchingHttpCache.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

/*
* This file is part of the FOSHttpCache package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace FOS\HttpCache\SymfonyCache;

use Symfony\Component\HttpKernel\HttpCache\HttpCache;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;

/**
* Base class for enhanced Symfony reverse proxy based on the symfony component.
*
* <b>When using FOSHttpCacheBundle, look at FOS\HttpCacheBundle\HttpCache instead.</b>
*
* This kernel supports event subscribers that can act on the events defined in
* FOS\HttpCache\SymfonyCache\Events and may alter the request flow.
*
* @author Jérôme Vieilledent <[email protected]> (courtesy of eZ Systems AS)
*
* {@inheritdoc}
*/
abstract class EventDispatchingHttpCache extends HttpCache
{
/**
* @var EventDispatcherInterface
*/
private $eventDispatcher;

/**
* Get event dispatcher
*
* @return EventDispatcherInterface
*/
public function getEventDispatcher()
{
if (null === $this->eventDispatcher) {
$this->eventDispatcher = new EventDispatcher();
}

return $this->eventDispatcher;
}

/**
* Add subscriber
*
* @param EventSubscriberInterface $subscriber
*/
public function addSubscriber(EventSubscriberInterface $subscriber)
{
$this->getEventDispatcher()->addSubscriber($subscriber);
}

/**
* {@inheritDoc}
*
* Adding the Events::PRE_HANDLE event.
*/
public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
{
if ($this->getEventDispatcher()->hasListeners(Events::PRE_HANDLE)) {
$event = new CacheEvent($this, $request);
$this->getEventDispatcher()->dispatch(Events::PRE_HANDLE, $event);
if ($event->getResponse()) {
return $event->getResponse();
}
}

return parent::handle($request, $type, $catch);
}
}
20 changes: 20 additions & 0 deletions src/SymfonyCache/Events.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

/*
* This file is part of the FOSHttpCache package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace FOS\HttpCache\SymfonyCache;

/**
* Events used in the customized Symfony built-in reverse proxy HttpCache.
*/
final class Events
{
const PRE_HANDLE = 'fos_http_cache.pre_handle';
}
Loading