Ведение сеанса для запросов, включенных в ESI
У меня проблемы с настройкой Varnish для правильной обработки файлов cookie сеанса для включенных в ESI подзапросов.
Фон, SSCCE
Три файла: index.php
, navigation.php
а также footer.php
объединены с помощью ESI, где первые два файла с состоянием, но только index.php
кэшируется, в то время как footer.php
полностью без гражданства.
### index.php
<?php
session_start();
header('Cache-Control: public, s-maxage=10');
header('Surrogate-Control: content="ESI/1.0"');
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Varnish test</title>
</head>
<body>
<esi:include src="http://localhost/WWW/navigation.php" />
<p>Primary content: <?php echo date('r') ?></p>
<esi:include src="http://localhost/WWW/footer.php" />
</body>
</html>
### footer.php
<?php
header('Cache-Control: public, s-maxage=20');
?>
<p>Footer: <?php echo date('r') ?></p>
### navigation.php
<?php
session_start();
if (!isset($_SESSION['counter'])) {
$_SESSION['counter'] = 0;
}
$_SESSION['counter'] += 1;
header('Cache-Control: private');
?>
<p>Navigation: <?php echo $_SESSION['counter'] ?></p>
Конфигурация лака VCL:
sub vcl_recv {
set req.http.Surrogate-Capability = "abc=ESI/1.0";
}
sub vcl_fetch {
if (beresp.http.Surrogate-Control ~ "ESI/1.0") {
unset beresp.http.Surrogate-Control;
set beresp.do_esi = true;
}
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
}
Желаемый результат
Я хотел бы увидеть index.php
/footer.php
загружается из кеша, очищается каждые 10/20 секунд, пока navigation.php
загружается непосредственно с внутреннего сервера. Конечно, самая первая просьба index.php
не может быть кэширован как Set-Cookie
заголовок должен быть установлен, однако footer.php
может быть загружен из кэша с самого начала.
Как я мог этого добиться? Я знаю, что присутствие Cookie
Заголовок в HTTP-запросе вызывает промах кэша, но я не могу просто удалить его.
1 ответ
Скорее комментарий, чем ответ, но долго помещаться в одном.
В приведенном выше примере отсутствует экранирование VCL Varnish по умолчанию [1], Varnish всегда будет добавлять свою логику по умолчанию к вашему VCL-коду [2], если вы не избегаете этого.
В этом случае вам нужно как минимум:
sub vcl_recv {
set req.http.Surrogate-Capability = "abc=ESI/1.0";
return (lookup);
}
Varnish также не будет кэшировать какие-либо ответы, включая заголовок Set-Cookie, если вы не форсируете его.
[1] https://www.varnish-cache.org/docs/3.0/reference/vcl.html
[2] https://www.varnish-software.com/static/book/VCL_Basics.html