I have a basic PHP page being loaded through Varnish with a single ESI include that calls back to the server to set a cookie. The cookie is set with domain access and the like, but when called through ESI the cookie is never set. If you access the ESI include path directly, the cookie is set with no issue. I have even set my Varnish configuration to never cache anything, thinking the VCL could be killing the cookie.
This...
<esi:include src="/init.php?<?=http_build_query($_GET); ?>"></esi:include>
...includes this...
<?php
header("Cache-Control: no-cache, must-revalidate");
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
setcookie('superman', 'clark kent', 0, '/', '.whatever.com');
?>
I'm new with Varnish and ESI, so I'm starting to wonder if this is a known limitation (either with ESI or with Varnish's ESI implementation), but I can't find any discussion of my problem online.
An interesting question which has been asked -but not answered- before ( Setting Cookies via ESI:include, how? ). I don't think you can do it this way. With ESI-include, the ESI processor makes a separate request and replaces a part from the body, not the header. In order to make your preferred set-cookie behavior work correctly, the ESI specification should specify how to 'merge' all set-cookie headers.
See chapter six of the ESI spec: http://www.w3.org/TR/esi-lang
When an ESI template is processed, a separate request will need to be made for each include encountered. Implementations may use the original request's headers (e.g., Cookie, User-Agent, etc.) when doing so. Additionally, response headers from fragments (e.g., Set-Cookie, Server, Cache-Control, Last-Modified) may be ignored, and should not influence the assembled page.
Could you try to convert your set-cookie header in a javascript set-cookie script? This could be included in the body...