<div dir="ltr"><div>Hi,<br><br></div>I have been playing with Varnish for some time now. I will try to explain the scenario in a lengthy email that follows. However, here's the summary too. Please bear with me and take a look at the detailed scenario in case the summary doesn't make enough sense.<br>
<br><p><b>Summary</b>:<br></p><p>I would like to pass some query parameters from
 a source URL to an ESI URL that was returned while fetching the source 
URL object itself. Is there a way to do this?<br></p><br><b>Detailed Explanation:</b><br><br>My web application is a typical consumer web application with the following features:<br><ol><li>Consumer pages do not need Login/Signup. User identification takes place via a unique value passed as a query parameter.<br>
</li><li>Consumer pages show user's email in the header in case user identity was present in the URL's query parameters. These are absent in case the pages are being accessed without a user's identity.</li><li>
Some links on the page are also appended with the user's identity in case it was present with the parent page.</li><li>Every other piece of information on these pages is the same for every user, except for the links (3) and email shown in the header (2).</li>
<li>Listing pages contain pagination controls. Paged listings contain page number as one of the query parameters in the URL.<br></li><li>The whole system is RESTful and does not rely on sessions or even Cookies as of now.</li>
</ol><p>Given the above, I have come up with the following Varnish setup:</p><ol><li>vcl_recv - Extracts user identity and sets it on a custom request header such as X-UserIdentity. Cleans req.url by removing user specific query parameter and other front-end related query parameters such as Google Analytics query parameters used by GA's Javascript.</li>
<li>Backend always receives a request without the user's identity so that single copy of the parent page can be cached.</li><li>Internal links on the parent page that require user's identity are rendered via <esi:include> tags. Similarly, email shown in the header is also replaced by an <esi:include> which calls an HTTP end-point which is capable of returning a user's email if an identity was provided.</li>
</ol><p>Problem:</p><ol><li>ESI URLs can't contain any user specific parameters. If they do, the first user hit will be cached and every subsequent request will result in reflecting the first user's identity. This is not desired at all.<br>
</li><li>Since ESI URLs do not contain any user specific parameters, the onus of adding user context lies with Varnish (since Varnish vcl_recv is where user's identity is removed).<br></li><li>I tried setting user identity in a request header for the parent URL (as explained above in 1. vcl_recv). This header is lost while fetching ESI URLs.</li>
<li>I tried setting a cookie in vcl_deliver. However, the cookie is inaccessible to the ESI URL fetch initiated during the same cycle. This is probably because the cookie is actually set *after* the first parent request completes and a response is sent back to the browser. I would want to make the cookie accessible *during* the parent request's ESI processing activity.</li>
</ol><p>--</p><p>Nikhil Lanjewar</p><p><a href="http://twitter.com/rhetonik">http://twitter.com/rhetonik</a><br></p></div>