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);
}
}