Varnish not processing ESI includes

落爺英雄遲暮 提交于 2019-12-10 11:52:38

问题


I'm trying to setup Varnish to process ESI includes on a local environment.

I am running varnish in a virtual machine and the content is running on the host machine.

I have two files "index.html" and "test.html". These are both stored in a folder called "esi" in the docroot of an apache server.

index.html

<h1>It Works!</h1>
<esi:include src="test.html" /> 

test.html

<p>ESI HAS BEEN INCLUDED</p>

Varnish is running on the virtual machine on port 8000. So I access it here: http://192.168.56.101:8000/esi/

in /etc/varnish/default.vcl on the virtual machine I have added the followin config to the bottom of the file:

sub vcl_fetch {
   set beresp.do_esi = true; /* Do ESI processing               */
   set beresp.ttl = 24 h;    /* Sets the TTL on the HTML above  */
}

With the idea that it should process ESI on ALL requests (Dont care if its bad practice just trying to get this thing to work :))

The result when I load http://192.168.56.101:8000/esi/ is:

<h1>It Works!</h1>
<esi:include src="test.html" />

ie. the ESI is shown in the markup, it is not being processed.

I have checked the Varnish log, however there are no errors in there and nothing related to ESIs.

Can anyone see what I am doing wrong here? Let me know if more information is needed.. thanks


回答1:


If your esi include src is "test.html" then varnish will be sending that request to your default backend, which is 127.0.0.1. I believe you need to configure a second backend for your remote server. Something like this:

backend default {
    .host = "127.0.0.1";
    .port = "8000";
}

backend hostmachine {
    .host = "50.18.104.129"; # Enter your IP address here
    .port = "80";
}

Then in your sub vcl_recv you need to redirect traffic that has /esi/ in the URL to the remote server.

sub vcl_recv {
      if (req.url ~ "^/esi/") {
            set req.backend = hostmachine;
            set req.http.host = "www.correctdomainname.com";
      } else {
            set req.backend = default;
      }
}

I'm working on the same thing right now so give it a try and let me know if it works for you.




回答2:


Varnish only implemented a small subset of ESI. As of 2.1 three ESI statements:

    esi:include
    esi:remove
    <!--esi ...-->

Content substitution based on variables and cookies is not implemented but is on the roadmap. Varnish will not process ESI instructions in HTML comments. For ESI to work you need to activate ESI processing in VCL, like this:

sub vcl_fetch {
if (req.url == "/index.html") {
   set beresp.do_esi = true; /* Do ESI processing               */
   set beresp.ttl = 24 h;    /* Sets the TTL on the HTML above  */
} elseif (req.url == "/test.html") {
   set beresp.ttl = 1m;      /* Sets a one minute TTL on        */
                             /*  the included object            */
}

}




回答3:


For ESI works (varnish 3.x), the first char must be a "<" so simply add HTML structure

Here my test :

index.php

<html>
<head>
    <title></title>
</head>
<body>
<?php

    $now = new \DateTime('now');
    echo "hello world from index.php ".$now->format('Y-m-d H:i:s');
?>

<br/>

<esi:include src="/date.php"/>

<br/>

<esi:remove>
    ESI NOT AVAILABLE
</esi:remove>

<br/>

<!--esi
ESI AVAILABLE !!

-->
</body>
</html>

date.php

<?php
$now = new \DateTime('now');
echo "hello world from date.php ".$now->format('Y-m-d H:i:s');

Output :

hello world from index.php 2014-08-21 10:45:29
hello world from date.php 2014-08-21 10:46:35



回答4:


Make sure your config is read by varnish. If you are running varnish in a docker container you might have to rebuild it.

You can change your config to something ridiculous and see if it catches it. For instance change the backend to w3.org.

If this still gives you the same result, you config isn't used.



来源:https://stackoverflow.com/questions/10092146/varnish-not-processing-esi-includes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!