friendsofsymfony / foshttpcachebundle Goto Github PK
View Code? Open in Web Editor NEWUse the FOSHttpCache library in your Symfony projects
Home Page: http://foshttpcachebundle.readthedocs.io
License: Other
Use the FOSHttpCache library in your Symfony projects
Home Page: http://foshttpcachebundle.readthedocs.io
License: Other
we should try-catch exceptions in the InvalidationListener to avoid breaking the response, but make sure they get logged by having a listener for Events::PROXY_RESPONSE_ERROR and Events::PROXY_UNREACHABLE_ERROR.
The CacheManager does not need the full RouterInterface so it should typehint the smaller interface
An annotation to refresh paths/routes is still missing:
@Refresh
refresh
param (default = false
) to invalidateRoute
and invalidatePath
; this option is cleaner and has my preference.The CacheAuthorizationListener listener returns immediately after Symfony's security check for HEAD requests. Currently, it returns an empty response. We can make the listener more useful, though, by returning a hash based on the user's roles. That hash can then be set as a custom header. If the caching proxy is then configured to vary on that header, different responses for different user roles could be cached. Additionally, you'd still be sure each user only sees content that he has access to (because of Symfony's security check).
The user hash should be definable by the user. Perhaps from configuration (include_role
or something?) but preferably by throwing an event (build_user_hash
or something) that the user can add a listener for. This bundle then has its own listener with some sane defaults.
This idea is inspired by the very nice context aware caching in ez Publish. But whereas their solution requires a Varnish module to be installed (CURL), I think our solution will work with plain VCL restart
.
@ddeboer said in #42: We should also standardize whether we user EventListeners or EventSubscribers (we now have both). EventSubscribers are easier to configure, but are tied closer to Symfony because they have to implement EventSubscriberInterface. Which do you prefer?
and i think going for subscriber sounds right to me.
http://symfony.com/doc/current/components/console/events.html#the-consoleevents-terminate-event
probably we can just add a method to the InvalidationListener that forwards to the right internal method.
check if this is an issue or not: #57 (comment)
Our CacheControlSubscriber overrides any caching headers the user may have set manually ($response->setMaxAge()
etc.), except in the case of Vary. @dbu Is this intended behaviour? If so, we should document it clearly.
why is there a difference between annotations and the configuration for creating tag headers? could these not just be 2 different ways to tell the same tools what they have to do? or is that already the case?
some sort of mapping (annotations, xml etc) to define how to compute an etag from an object. this might require param converters.
This Nginx module adds purge handling to Nginx.
friendsofsymfony/http-cache: 1.*
and remove the @dev
For testing the configuration and annotations, it may be useful to have tests against a Symfony application.
and profit to clean up the configuration format. only for the existing features for now.
Options:
guzzle is only used with the varnish invalidator. we should move that from require to suggest and check in the DI extension if varnish is activated if guzzle is available.
we should allow to configure a global RuleMatcher in the tag_listener section instead of hardcoding the response codes (see TagSubscriber $response->isSuccessful).
i would only allow the match_response and the additional_cacheable_status options i guess, matching the request makes no sense for tags.
figure out if we need to make the security context optional for sites that do not have a firewall over all routes:
Add some info()
to Configuration.php
.
Have concrete HTTP cache implementations implement interface PurgeInterface
, and, optionally, BanInterface
. For instance:
Should we copy the Varnish names (purge and ban) or stick to our own names, such as invalidateUrl
and invalidateRegex
or something like that?
As discussed in #42, the naming is a bit off. Rename in the component and the bundle. This will be a hard BC break of course. If we can merge the nginx PR first, we could do the change in one go, otherwise we break it again.
for using in the bundle, i think it makes sense to have a proxy_client.varnish
and other proxy_client.X
and then define the alias from the DI class for default_proxy_client. that way some really complicated setup could even run both varnish and nginx or symfony built-in cache clients, and add his own services with the other clients.
instead of sending special requests to the varnish frontend (and have rules that check every request for being a purge from the webserver), one could also use the telnet interface to send purge requests.
the user of the bundle should be able to call the same methods whether he uses the frontend purge controller or the one using the administration port.
http://www.varnish-cache.org/docs/3.0/reference/varnishd.html#management-interface
http://www.varnish-cache.org/docs/2.1/reference/varnishd.html#management-interface
see also TODO in https://github.com/liip/CacheControlBundle/blob/master/Helper/Varnish.php
In the request matching to decide on cache rules, there is an unless_role
option that skips the rule if the user is authorized and has a specific role. This only ever makes sense when nothing is cached or responses vary on the cookie, so can only really set the max-age. @lsmith77 explained that it was built in LiipCacheControlBundle to set no cache for admin users in a project.
This option feels weird to me. To cover the use case, a match_permission would make much more sense. Then we could do a granted check if there is a security context with a token and apply that rule if its granted.
in https://github.com/ddeboer/FOSHttpCacheBundle/blob/master/Resources/doc/varnish.md#purge we say to also purge on cache miss. after being confused, i assume that this is to still purge variants if the requested url was not matched? if that is correct, we might put a note there.
i fear that the expression language example in the annotation doc are wrong. the TagSubscriber only passes in request and response, but not the parameters to the method that was called. if we can manage to provide the named parameters, that would be awesome. otherwise we should change the examples to use the request object.
i also got the impression that * @Tag(expression="'news-'~article.id")
mentioned in
http://foshttpcachebundle.readthedocs.org/en/latest/tagging.html#invalidate-tags will not work. for me, expression language did not behave like twig, i had to write article.getId().
setting the no-cache header replaces all other cache headers. instead we should add a no-cache instruction. we could also check if max_age or s_maxage are > 0 and throw an error in that case (in configuration validation) as it makes no sense.
create a unit test for the flash message listener
Hi,
When I use your command (composer require friendsofsymfony/http-cache-bundle:@stable) to install the bundle, it shows the error:
Problem 1
- The requested package friendsofsymfony/http-cache-bundle could not be found in any version, there may be a typo in the package name.
Problem 2
- Installation request for symfony/framework-standard-edition 2.5.x-dev -> satisfiable by symfony/framework-standard-edition[2.5.x-dev].
- symfony/framework-standard-edition 2.5.x-dev requires friendsofsymfony/http-cache-bundle @stable -> no matching package found.
Please help me with this issues. Thanks
once #57 is done, we should look into a logout listener to invalidate cached context hash requests.
The bundle is still geared primarily towards Varnish. Let’s change this so it becomes possible to configure Nginx, too.
Currently, everything uses protected properties in the bundle. This means that all properties are potential extension points, and a change on them will be a BC break.
As we want to follow semver, I think we should rather use the private visibility for properties and switch to protected only for places where we decide to expose a supported extension point. This will make thing easier to manage BC. A request to increase the visibility will need to be justified with a use case for the extension point (allowing us to decide whether it is the right way to provide such extension point).
Note that this rule will be common for our users, as it is the rule applied in Symfony itself.
what do you think about it ?
As mentioned here.
Add a controller annotation and YML configuration option that invalidate all methods in a controller when they and their routes names follow a convention, such as the of the FOSRestBundle.
This is currently possible in the Driebit bundle, but that only supports purge requests. Allowing invalidation requests to be done in parallel becomes more complex when adding ban and refresh support.
Two options:
purge(string[] $urls)
(multiple URLs together), ban(string[] $urls)
(but how to have custom headers per URL?). Maybe a custom Request
that holds both URL and headers class could help here, so we get ban(Request[] $requests)
. Even then, it's impossible to combine all ban, purge and refresh requests together.purge($url)
(single URL), ban($url, $headers, …)
. This does mean more duplicate code, though, between the Varnish and Nginx classes. We could have an AbstractHttpCache
class that takes care of queueing and flushing, of course.Am I missing something?
There’s no way to override the default X-Cache-Debug
.
actually the whole code about cache invalidation is not specific to symfony, but could run without. maybe it would make sense to split everything non-symfony into a component and have the bundle just provide the DI configuration and the request listeners and similar symfony related functionality.
now would be a good time to do that, as the namespace changes are a BC break for everybody anyways. doing it later would be a pain as we would change namespaces.
we could try to make the caching header configuration extensible, for example for this use case: symfony-cmf/content-bundle#36
The default X-Cache-Tags
should be overridable in the bundle’s config.
As discussed elsewhere, our implementation of the user context functionality requires a route to be defined. We now tell users to add that route themselves. It would be more user-friendly to do that for them, probably based on a config parameter. If we change this, we should remember to update the docs accordingly.
currently, we have a ton of match criteria for the rules mixed up with the header configuration in case this matches.
path: ^/$
host: ^login.example.com$
methods: [ GET, HEAD ]
unless_role: ROLE_NO_CACHE
...
controls: { public: false, max_age: 0, s_maxage: 0, last_modified: "-1 hour" }
vary: [Accept-Encoding, Accept-Language]
we maybe should group this:
match:
path: ^/$
host: ^login.example.com$
methods: [ GET, HEAD ]
unless_role: ROLE_NO_CACHE
...
controls: { public: false, max_age: 0, s_maxage: 0, last_modified: "-1 hour" }
vary: [Accept-Encoding, Accept-Language]
possibly with the option to specify just the path outside of the match and validation in configuration that you have exactly one of match
or a path
specified.
see also #33
i guess this is meant for when no caching is active. we could explain in the doc how to actually have the original ip in the request and not the varnish ip => http://symfony.com/doc/current/components/http_foundation/trusting_proxies.html - and explain that if the response depends on the client ip you most likely need to prevent proxies from caching it
the documentation should contain a configuration reference interlinked with a chapter on each feature that introduces to the why and how with minimal configuration examples. like the symfony and symfony cmf doc does with the Reference section and the chapters in the "Bundles" section. for us, it could be "Features" and "Configuration" i think.
see also the discussion in #92
Although Varnish makes more sense for any serious caching, it could be nice to support the Symfony reverse proxy as well, for out of the box caching.
Note: There is now a kernel provided in this bundle to support the user context with the reverse proxy. But no cache invalidation as of yet.
This issue is an archive of the original discussion. See HttpCache label issues for a list of all topics.
In our app we'd like to control all http caching using FOSHttpCache, we've found that some bundles add default cache headers that we would like to override.
It would be nice to have a global setting like:
force_header_overwrite: true | false
Or even a way of overriding just for one rule:
fos_http_cache:
cache_control:
rules:
# only match login.example.com
-
match:
host: ^login.example.com$
headers:
cache_control: { public: false, max_age: 0, s_maxage: 0, last_modified: "-1 hour" }
vary: [Accept-Encoding, Accept-Language]
force_overwrite: true | false
If this is something that is useful to the community I can implement it and do a PR.
Checklist:
repositories
from composer.json
@dev
Currently, the bundle supports only one value for host
. That's a bit silly, as an application could have multiple hostnames for which caches must be invalidated.
The CacheManager, which could as a layer on top of the HTTP proxy clients, is still unfinished.
tagResponse
that adds caching tags to responses (#2).we just merged a PR on LiipCacheControlBundle to make our varnish helper more flexible. we should port that over along with merging the rest of things.
Please add any doc issues to this list, so we don’t forget about them and we can fix them later in one go.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.