Symfony 2.4 ESI ошибка? (Debian 7 + nginx + Varnish + PHP 5.4 / PHP 5.5: ESI не работает - удивительное поведение PHP)

основы

Я сделал очень простое тестовое действие:

/**
 * @Route("/public/debug/varnish", name="debug_varnish")
 * @Template
 */
public function varnishAction()
{
    return [];
}
{# varnish.html.twig #}
<html>
<body>
    <h1>Layout</h1>
    <hr />
    {{ render_esi(controller('TestBundle:Debug:esi')) }}
</body>
</html>

Включенное действие и веточка не важны сейчас.

Тест

Лак нуждается в Surrogate-Control: content="ESI/1.0" Заголовок в ответе. Посмотрите, что происходит:

curl -H 'host:www.domain.com' -H 'Surrogate-Capability: abc=ESI/1.0' http://127.0.0.1:8080/public/debug/varnish

Ответ:

<html>
<body>
    <h1>Layout</h1>
    <hr />
    <esi:include src="/_proxy?_path=_format%3Dhtml%26_locale%3Den_US%26_controller%3DTestBundle%253ADebug%253Aesi" onerror="continue" />
</body>
</html>

Все в порядке! Но посмотрите заголовки:

curl -I -H 'host:www.domain.com' -H 'Surrogate-Capability: abc=ESI/1.0' http://127.0.0.1:8080/public/debug/varnish

Выход:

HTTP/1.1 200 OK
Server: nginx/1.2.1
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.5.9-1~dotdeb.1
Set-Cookie: PHPSESSID=k8jii3gkrha1js7edbbbqjjh32; path=/
Cache-Control: no-cache
Date: Tue, 18 Feb 2014 11:21:04 GMT

Нет Surrogate-Control заголовок!

Класс \Symfony\Component\HttpKernel\HttpCache\Esi

Существует очень-очень простая функция, которая добавляет Surrogate-Control заголовок, если содержание содержит <esi:include строка:

/**
 * Adds HTTP headers to specify that the Response needs to be parsed for ESI.
 *
 * This method only adds an ESI HTTP header if the Response has some ESI tags.
 *
 * @param Response $response A Response instance
 */
public function addSurrogateControl(Response $response)
{
    if (false !== strpos($response->getContent(), '<esi:include')) {
        $response->headers->set('Surrogate-Control', 'content="ESI/1.0"');
    }
}

Но это не так! Если это "правда". Когда я звоню с этим:

public function addSurrogateControl(Response $response)
{
    var_dump(false !== strpos($response->getContent(), '<esi:include'));
    if (false !== strpos($response->getContent(), '<esi:include')) {
        echo "before add header\n";
        $response->headers->set('Surrogate-Control', 'content="ESI/1.0"');
        echo "after add header\n";
    }
    echo "after if"
}
curl -H 'host:www.domain.com' -H 'Surrogate-Capability: abc=ESI/1.0' http://127.0.0.1:8080/public/debug/varnish

Ответ:

(bool) true
before add header
after add header
after if
<html>
<body>
    <h1>Layout</h1>
    <hr />
    <esi:include src="/_proxy?_path=_format%3Dhtml%26_locale%3Den_US%26_controller%3DTestBundle%253ADebug%253Aesi" onerror="continue" />
</body>
</html>
curl -I -H 'host:www.domain.com' -H 'Surrogate-Capability: abc=ESI/1.0' http://127.0.0.1:8080/public/debug/varnish

Выход:

HTTP/1.1 200 OK
Server: nginx/1.2.1
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.5.9-1~dotdeb.1
Set-Cookie: PHPSESSID=k8jii3gkrha1js7edbbbqjjh32; path=/
Cache-Control: no-cache
Date: Tue, 18 Feb 2014 11:21:04 GMT

ГДЕ Surrogate-Control HEADER?: -o

Больше тестов:

public function addSurrogateControl(Response $response)
{
    // [1]
    if (false !== strpos($response->getContent(), '<esi:include')) {
        // [2]
    }
    // [3]
}

С $response->headers->set('Surrogate-Control', 'content="ESI/1.0"'); а также (!!!) header('Test: test OK'):

  • [1] место: РАБОТАЙ!
  • [2] оригинальное место: не работает:(
  • [3] место: РАБОТАЙ!

Хорошо. Так что, если ЛЮБАЯ модификация заголовка находится в IF не работает Зачем?

Магия

Когда я меняю $response->getContent() с 'test <esi:include test' в if состояние, то все работает нормально. Response учебный класс getContent() функция:

public function getContent()
{
    return $this->content;
}

Я не понимаю:-/

0 ответов

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