Ведение сеанса для запросов, включенных в 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

Другие вопросы по тегам