Symfony Con, December 6th, 2018
{% if app.request.hasPreviousSession %} {% for message in app.flashes('notice') %} <div class="flash-notice"> {{ message }} </div> {% endfor %} {% endif %}
sub vcl_recv { # using a capturing sub pattern, extract the continuous string of # alphanumerics that immediately follows "PHPSESSID=" set req.http.X-Varnish-PHP_SID = regsuball(req.http.Cookie, ";? ?PHPSESSID=([a-zA-Z0-9]+)( |;| ;).*","\1"); if (req.X-Varnish-PHP_SID != "") { set req.http.Cookie = req.X-Varnish-PHP_SID; } else { unset req.http.Cookie; } unset req.X-Varnish-PHP_SID; }
https://www.varnish-cache.org/docs/4.1/users-guide/increasing-your-hitrate.html
$(document).ready(function () { if (is_editor()) { $("#labels-edit").show(); $("#milestone-edit").show(); $("#assignee-edit").show(); } });
$(document).ready(function () { $.ajax({ url: "/sidebar.html" }).done(function( html ) { $( "#sidebar" ).append( html ); }); });
Cache-Control: no-cache
Vary: Cookie
Cache-Control: public, s-maxage: ...
// Symfony 3.4+ overwrites caching headers when session was used. // Need to explicitly tell it we intend to cache the response use Symfony\Component\HttpKernel\EventListener\AbstractSessionListener; ... $response->headers->set( AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER, 'true');
sub vcl_recv { // ... if (req.method != "GET" && req.method != "HEAD") { /* We only deal with GET and HEAD by default */ return (pass); } if (req.http.Authorization || req.http.Cookie) { /* Not cacheable by default */ return (pass); } return (hash); }
// default.vcl sub vcl_recv { // ... if (req.method != "GET" && req.method != "HEAD") { /* We only deal with GET and HEAD by default */ return (pass); } // Cache lookup even with Cookie or Authorization header return (hash); }
<html> <body> Main body. <esi:include src="fragment.php" /> </body> </html>
And activate ESI in Varnish
# app/config/config.yml framework: esi: { enabled: true } fragments: { path: /_fragment }Make sure /_fragment is not reachable from the outside
{# index.html.twig #} {% render_esi(controller( 'AppBundle:Comments:comments', {'param': 42 })) %}
sub vcl_recv { ... // Copy client request headers to auth request curl.header_add_all(); // We go through varnish itself to cache curl.header_add("Host: auth"); curl.get("http://localhost/"); if (200 != curl.status()) { return (synth(curl.status())); } set req.http.X-User-Context = curl.header("X-User-Context"); curl.free(); ... }
sub vcl_recv { // Cache auth lookup if ("auth" == req.http.Host) { if (!client.ip ~ self) { return (synth(405, "Not allowed")); } set req.backend_hint = auth; // force caching despite auth headers return (hash); } ... }
class RoleProvider implements ContextProvider { public function updateUserContext( UserContext $context ) { ... $roles = array_map(function (Role $role) { return $role->getRole(); }, $token->getRoles()); // Order should not change hash sort($roles); $context->addParameter('roles', $roles); } }